basic_io_object.hpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. //
  2. // basic_io_object.hpp
  3. // ~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2025 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_BASIC_IO_OBJECT_HPP
  11. #define BOOST_ASIO_BASIC_IO_OBJECT_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #if !defined(BOOST_ASIO_NO_DEPRECATED) \
  17. || defined(GENERATING_DOCUMENTATION)
  18. #include <boost/asio/io_context.hpp>
  19. #include <boost/asio/detail/push_options.hpp>
  20. namespace boost {
  21. namespace asio {
  22. namespace detail
  23. {
  24. // Type trait used to determine whether a service supports move.
  25. template <typename IoObjectService>
  26. class service_has_move
  27. {
  28. private:
  29. typedef IoObjectService service_type;
  30. typedef typename service_type::implementation_type implementation_type;
  31. template <typename T, typename U>
  32. static auto asio_service_has_move_eval(T* t, U* u)
  33. -> decltype(t->move_construct(*u, *u), char());
  34. static char (&asio_service_has_move_eval(...))[2];
  35. public:
  36. static const bool value =
  37. sizeof(asio_service_has_move_eval(
  38. static_cast<service_type*>(0),
  39. static_cast<implementation_type*>(0))) == 1;
  40. };
  41. }
  42. /// (Deprecated) Base class for all I/O objects.
  43. /**
  44. * @note All I/O objects are non-copyable. However, when using C++0x, certain
  45. * I/O objects do support move construction and move assignment.
  46. */
  47. #if defined(GENERATING_DOCUMENTATION)
  48. template <typename IoObjectService>
  49. #else
  50. template <typename IoObjectService,
  51. bool Movable = detail::service_has_move<IoObjectService>::value>
  52. #endif
  53. class BOOST_ASIO_DEPRECATED_MSG("Deprecated without replacement")
  54. basic_io_object
  55. {
  56. public:
  57. /// The type of the service that will be used to provide I/O operations.
  58. typedef IoObjectService service_type;
  59. /// The underlying implementation type of I/O object.
  60. typedef typename service_type::implementation_type implementation_type;
  61. /// Get the io_context associated with the object.
  62. /**
  63. * This function may be used to obtain the io_context object that the I/O
  64. * object uses to dispatch handlers for asynchronous operations.
  65. *
  66. * @return A reference to the io_context object that the I/O object will use
  67. * to dispatch handlers. Ownership is not transferred to the caller.
  68. */
  69. boost::asio::io_context& get_io_context()
  70. {
  71. return service_.get_io_context();
  72. }
  73. /// Get the io_context associated with the object.
  74. /**
  75. * This function may be used to obtain the io_context object that the I/O
  76. * object uses to dispatch handlers for asynchronous operations.
  77. *
  78. * @return A reference to the io_context object that the I/O object will use
  79. * to dispatch handlers. Ownership is not transferred to the caller.
  80. */
  81. boost::asio::io_context& get_io_service()
  82. {
  83. return service_.get_io_context();
  84. }
  85. /// The type of the executor associated with the object.
  86. typedef boost::asio::io_context::executor_type executor_type;
  87. /// Get the executor associated with the object.
  88. executor_type get_executor() noexcept
  89. {
  90. return service_.get_io_context().get_executor();
  91. }
  92. protected:
  93. /// Construct a basic_io_object.
  94. /**
  95. * Performs:
  96. * @code get_service().construct(get_implementation()); @endcode
  97. */
  98. explicit basic_io_object(boost::asio::io_context& io_context)
  99. : service_(boost::asio::use_service<IoObjectService>(io_context))
  100. {
  101. service_.construct(implementation_);
  102. }
  103. #if defined(GENERATING_DOCUMENTATION)
  104. /// Move-construct a basic_io_object.
  105. /**
  106. * Performs:
  107. * @code get_service().move_construct(
  108. * get_implementation(), other.get_implementation()); @endcode
  109. *
  110. * @note Available only for services that support movability,
  111. */
  112. basic_io_object(basic_io_object&& other);
  113. /// Move-assign a basic_io_object.
  114. /**
  115. * Performs:
  116. * @code get_service().move_assign(get_implementation(),
  117. * other.get_service(), other.get_implementation()); @endcode
  118. *
  119. * @note Available only for services that support movability,
  120. */
  121. basic_io_object& operator=(basic_io_object&& other);
  122. /// Perform a converting move-construction of a basic_io_object.
  123. template <typename IoObjectService1>
  124. basic_io_object(IoObjectService1& other_service,
  125. typename IoObjectService1::implementation_type& other_implementation);
  126. #endif // defined(GENERATING_DOCUMENTATION)
  127. /// Protected destructor to prevent deletion through this type.
  128. /**
  129. * Performs:
  130. * @code get_service().destroy(get_implementation()); @endcode
  131. */
  132. ~basic_io_object()
  133. {
  134. service_.destroy(implementation_);
  135. }
  136. /// Get the service associated with the I/O object.
  137. service_type& get_service()
  138. {
  139. return service_;
  140. }
  141. /// Get the service associated with the I/O object.
  142. const service_type& get_service() const
  143. {
  144. return service_;
  145. }
  146. /// Get the underlying implementation of the I/O object.
  147. implementation_type& get_implementation()
  148. {
  149. return implementation_;
  150. }
  151. /// Get the underlying implementation of the I/O object.
  152. const implementation_type& get_implementation() const
  153. {
  154. return implementation_;
  155. }
  156. private:
  157. basic_io_object(const basic_io_object&);
  158. basic_io_object& operator=(const basic_io_object&);
  159. // The service associated with the I/O object.
  160. service_type& service_;
  161. /// The underlying implementation of the I/O object.
  162. implementation_type implementation_;
  163. };
  164. // Specialisation for movable objects.
  165. template <typename IoObjectService>
  166. class BOOST_ASIO_DEPRECATED_MSG("Deprecated without replacement")
  167. basic_io_object<IoObjectService, true>
  168. {
  169. public:
  170. typedef IoObjectService service_type;
  171. typedef typename service_type::implementation_type implementation_type;
  172. boost::asio::io_context& get_io_context()
  173. {
  174. return service_->get_io_context();
  175. }
  176. boost::asio::io_context& get_io_service()
  177. {
  178. return service_->get_io_context();
  179. }
  180. typedef boost::asio::io_context::executor_type executor_type;
  181. executor_type get_executor() noexcept
  182. {
  183. return service_->get_io_context().get_executor();
  184. }
  185. protected:
  186. explicit basic_io_object(boost::asio::io_context& io_context)
  187. : service_(&boost::asio::use_service<IoObjectService>(io_context))
  188. {
  189. service_->construct(implementation_);
  190. }
  191. basic_io_object(basic_io_object&& other)
  192. : service_(&other.get_service())
  193. {
  194. service_->move_construct(implementation_, other.implementation_);
  195. }
  196. template <typename IoObjectService1>
  197. basic_io_object(IoObjectService1& other_service,
  198. typename IoObjectService1::implementation_type& other_implementation)
  199. : service_(&boost::asio::use_service<IoObjectService>(
  200. other_service.get_io_context()))
  201. {
  202. service_->converting_move_construct(implementation_,
  203. other_service, other_implementation);
  204. }
  205. ~basic_io_object()
  206. {
  207. service_->destroy(implementation_);
  208. }
  209. basic_io_object& operator=(basic_io_object&& other)
  210. {
  211. service_->move_assign(implementation_,
  212. *other.service_, other.implementation_);
  213. service_ = other.service_;
  214. return *this;
  215. }
  216. service_type& get_service()
  217. {
  218. return *service_;
  219. }
  220. const service_type& get_service() const
  221. {
  222. return *service_;
  223. }
  224. implementation_type& get_implementation()
  225. {
  226. return implementation_;
  227. }
  228. const implementation_type& get_implementation() const
  229. {
  230. return implementation_;
  231. }
  232. private:
  233. basic_io_object(const basic_io_object&);
  234. void operator=(const basic_io_object&);
  235. IoObjectService* service_;
  236. implementation_type implementation_;
  237. };
  238. } // namespace asio
  239. } // namespace boost
  240. #include <boost/asio/detail/pop_options.hpp>
  241. #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
  242. // || defined(GENERATING_DOCUMENTATION)
  243. #endif // BOOST_ASIO_BASIC_IO_OBJECT_HPP