// // io_object_impl.hpp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 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_IO_OBJECT_IMPL_HPP #define ASIO_DETAIL_IO_OBJECT_IMPL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp" #include "asio/execution/context.hpp" #include "asio/io_context.hpp" #include "asio/query.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class io_object_impl { public: // The type of the service that will be used to provide I/O operations. typedef IoObjectService service_type; // The underlying implementation type of I/O object. typedef typename service_type::implementation_type implementation_type; // The type of the executor associated with the object. typedef Executor executor_type; // Construct an I/O object using an executor. explicit io_object_impl(const executor_type& ex) : service_(&asio::use_service( io_object_impl::get_context(ex))), executor_(ex) { service_->construct(implementation_); } // Construct an I/O object using an execution context. template explicit io_object_impl(ExecutionContext& context, typename enable_if::value>::type* = 0) : service_(&asio::use_service(context)), executor_(context.get_executor()) { service_->construct(implementation_); } #if defined(ASIO_HAS_MOVE) // Move-construct an I/O object. io_object_impl(io_object_impl&& other) : service_(&other.get_service()), executor_(other.get_executor()) { service_->move_construct(implementation_, other.implementation_); } // Perform a converting move-construction of an I/O object. template io_object_impl(io_object_impl&& other) : service_(&asio::use_service( io_object_impl::get_context(other.get_executor()))), executor_(other.get_executor()) { service_->converting_move_construct(implementation_, other.get_service(), other.get_implementation()); } #endif // defined(ASIO_HAS_MOVE) // Destructor. ~io_object_impl() { service_->destroy(implementation_); } #if defined(ASIO_HAS_MOVE) // Move-assign an I/O object. io_object_impl& operator=(io_object_impl&& other) { if (this != &other) { service_->move_assign(implementation_, *other.service_, other.implementation_); executor_.~executor_type(); new (&executor_) executor_type( std::move(other.executor_)); service_ = other.service_; } return *this; } #endif // defined(ASIO_HAS_MOVE) // Get the executor associated with the object. const executor_type& get_executor() ASIO_NOEXCEPT { return executor_; } // Get the service associated with the I/O object. service_type& get_service() { return *service_; } // Get the service associated with the I/O object. const service_type& get_service() const { return *service_; } // Get the underlying implementation of the I/O object. implementation_type& get_implementation() { return implementation_; } // Get the underlying implementation of the I/O object. const implementation_type& get_implementation() const { return implementation_; } private: // Helper function to get an executor's context. template static execution_context& get_context(const T& t, typename enable_if::value>::type* = 0) { return asio::query(t, execution::context); } // Helper function to get an executor's context. template static execution_context& get_context(const T& t, typename enable_if::value>::type* = 0) { return t.context(); } // Disallow copying and copy assignment. io_object_impl(const io_object_impl&); io_object_impl& operator=(const io_object_impl&); // The service associated with the I/O object. service_type* service_; // The underlying implementation of the I/O object. implementation_type implementation_; // The associated executor. executor_type executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IO_OBJECT_IMPL_HPP