io_object_impl.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. //
  2. // io_object_impl.hpp
  3. // ~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2021 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_IO_OBJECT_IMPL_HPP
  11. #define BOOST_ASIO_DETAIL_IO_OBJECT_IMPL_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <new>
  16. #include <boost/asio/detail/config.hpp>
  17. #include <boost/asio/detail/type_traits.hpp>
  18. #include <boost/asio/execution/executor.hpp>
  19. #include <boost/asio/execution/context.hpp>
  20. #include <boost/asio/io_context.hpp>
  21. #include <boost/asio/query.hpp>
  22. #include <boost/asio/detail/push_options.hpp>
  23. namespace boost {
  24. namespace asio {
  25. namespace detail {
  26. template <typename IoObjectService,
  27. typename Executor = io_context::executor_type>
  28. class io_object_impl
  29. {
  30. public:
  31. // The type of the service that will be used to provide I/O operations.
  32. typedef IoObjectService service_type;
  33. // The underlying implementation type of I/O object.
  34. typedef typename service_type::implementation_type implementation_type;
  35. // The type of the executor associated with the object.
  36. typedef Executor executor_type;
  37. // Construct an I/O object using an executor.
  38. explicit io_object_impl(int, const executor_type& ex)
  39. : service_(&boost::asio::use_service<IoObjectService>(
  40. io_object_impl::get_context(ex))),
  41. executor_(ex)
  42. {
  43. service_->construct(implementation_);
  44. }
  45. // Construct an I/O object using an execution context.
  46. template <typename ExecutionContext>
  47. explicit io_object_impl(int, int, ExecutionContext& context)
  48. : service_(&boost::asio::use_service<IoObjectService>(context)),
  49. executor_(context.get_executor())
  50. {
  51. service_->construct(implementation_);
  52. }
  53. #if defined(BOOST_ASIO_HAS_MOVE)
  54. // Move-construct an I/O object.
  55. io_object_impl(io_object_impl&& other)
  56. : service_(&other.get_service()),
  57. executor_(other.get_executor())
  58. {
  59. service_->move_construct(implementation_, other.implementation_);
  60. }
  61. // Perform a converting move-construction of an I/O object.
  62. template <typename IoObjectService1, typename Executor1>
  63. io_object_impl(io_object_impl<IoObjectService1, Executor1>&& other)
  64. : service_(&boost::asio::use_service<IoObjectService>(
  65. io_object_impl::get_context(other.get_executor()))),
  66. executor_(other.get_executor())
  67. {
  68. service_->converting_move_construct(implementation_,
  69. other.get_service(), other.get_implementation());
  70. }
  71. #endif // defined(BOOST_ASIO_HAS_MOVE)
  72. // Destructor.
  73. ~io_object_impl()
  74. {
  75. service_->destroy(implementation_);
  76. }
  77. #if defined(BOOST_ASIO_HAS_MOVE)
  78. // Move-assign an I/O object.
  79. io_object_impl& operator=(io_object_impl&& other)
  80. {
  81. if (this != &other)
  82. {
  83. service_->move_assign(implementation_,
  84. *other.service_, other.implementation_);
  85. executor_.~executor_type();
  86. new (&executor_) executor_type(other.executor_);
  87. service_ = other.service_;
  88. }
  89. return *this;
  90. }
  91. #endif // defined(BOOST_ASIO_HAS_MOVE)
  92. // Get the executor associated with the object.
  93. const executor_type& get_executor() BOOST_ASIO_NOEXCEPT
  94. {
  95. return executor_;
  96. }
  97. // Get the service associated with the I/O object.
  98. service_type& get_service()
  99. {
  100. return *service_;
  101. }
  102. // Get the service associated with the I/O object.
  103. const service_type& get_service() const
  104. {
  105. return *service_;
  106. }
  107. // Get the underlying implementation of the I/O object.
  108. implementation_type& get_implementation()
  109. {
  110. return implementation_;
  111. }
  112. // Get the underlying implementation of the I/O object.
  113. const implementation_type& get_implementation() const
  114. {
  115. return implementation_;
  116. }
  117. private:
  118. // Helper function to get an executor's context.
  119. template <typename T>
  120. static execution_context& get_context(const T& t,
  121. typename enable_if<execution::is_executor<T>::value>::type* = 0)
  122. {
  123. return boost::asio::query(t, execution::context);
  124. }
  125. // Helper function to get an executor's context.
  126. template <typename T>
  127. static execution_context& get_context(const T& t,
  128. typename enable_if<!execution::is_executor<T>::value>::type* = 0)
  129. {
  130. return t.context();
  131. }
  132. // Disallow copying and copy assignment.
  133. io_object_impl(const io_object_impl&);
  134. io_object_impl& operator=(const io_object_impl&);
  135. // The service associated with the I/O object.
  136. service_type* service_;
  137. // The underlying implementation of the I/O object.
  138. implementation_type implementation_;
  139. // The associated executor.
  140. executor_type executor_;
  141. };
  142. } // namespace detail
  143. } // namespace asio
  144. } // namespace boost
  145. #include <boost/asio/detail/pop_options.hpp>
  146. #endif // BOOST_ASIO_DETAIL_IO_OBJECT_IMPL_HPP