basic_io_object.hpp 7.7 KB

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