basic_io_object.hpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. //
  2. // basic_io_object.hpp
  3. // ~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2015 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 ASIO_BASIC_IO_OBJECT_HPP
  11. #define 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 "asio/detail/config.hpp"
  16. #include "asio/io_service.hpp"
  17. #include "asio/detail/push_options.hpp"
  18. namespace asio {
  19. #if defined(ASIO_HAS_MOVE)
  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 eval(T* t, U* u) -> decltype(t->move_construct(*u, *u), char());
  31. static char (&eval(...))[2];
  32. public:
  33. static const bool value =
  34. sizeof(service_has_move::eval(
  35. static_cast<service_type*>(0),
  36. static_cast<implementation_type*>(0))) == 1;
  37. };
  38. }
  39. #endif // defined(ASIO_HAS_MOVE)
  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(ASIO_HAS_MOVE) || 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. /// Get the io_service associated with the object.
  59. /**
  60. * This function may be used to obtain the io_service object that the I/O
  61. * object uses to dispatch handlers for asynchronous operations.
  62. *
  63. * @return A reference to the io_service object that the I/O object will use
  64. * to dispatch handlers. Ownership is not transferred to the caller.
  65. */
  66. asio::io_service& get_io_service()
  67. {
  68. return service.get_io_service();
  69. }
  70. protected:
  71. /// Construct a basic_io_object.
  72. /**
  73. * Performs:
  74. * @code get_service().construct(get_implementation()); @endcode
  75. */
  76. explicit basic_io_object(asio::io_service& io_service)
  77. : service(asio::use_service<IoObjectService>(io_service))
  78. {
  79. service.construct(implementation);
  80. }
  81. #if defined(GENERATING_DOCUMENTATION)
  82. /// Move-construct a basic_io_object.
  83. /**
  84. * Performs:
  85. * @code get_service().move_construct(
  86. * get_implementation(), other.get_implementation()); @endcode
  87. *
  88. * @note Available only for services that support movability,
  89. */
  90. basic_io_object(basic_io_object&& other);
  91. /// Move-assign a basic_io_object.
  92. /**
  93. * Performs:
  94. * @code get_service().move_assign(get_implementation(),
  95. * other.get_service(), other.get_implementation()); @endcode
  96. *
  97. * @note Available only for services that support movability,
  98. */
  99. basic_io_object& operator=(basic_io_object&& other);
  100. #endif // defined(GENERATING_DOCUMENTATION)
  101. /// Protected destructor to prevent deletion through this type.
  102. /**
  103. * Performs:
  104. * @code get_service().destroy(get_implementation()); @endcode
  105. */
  106. ~basic_io_object()
  107. {
  108. service.destroy(implementation);
  109. }
  110. /// Get the service associated with the I/O object.
  111. service_type& get_service()
  112. {
  113. return service;
  114. }
  115. /// Get the service associated with the I/O object.
  116. const service_type& get_service() const
  117. {
  118. return service;
  119. }
  120. /// (Deprecated: Use get_service().) The service associated with the I/O
  121. /// object.
  122. /**
  123. * @note Available only for services that do not support movability.
  124. */
  125. service_type& service;
  126. /// Get the underlying implementation of the I/O object.
  127. implementation_type& get_implementation()
  128. {
  129. return implementation;
  130. }
  131. /// Get the underlying implementation of the I/O object.
  132. const implementation_type& get_implementation() const
  133. {
  134. return implementation;
  135. }
  136. /// (Deprecated: Use get_implementation().) The underlying implementation of
  137. /// the I/O object.
  138. implementation_type implementation;
  139. private:
  140. basic_io_object(const basic_io_object&);
  141. basic_io_object& operator=(const basic_io_object&);
  142. };
  143. #if defined(ASIO_HAS_MOVE)
  144. // Specialisation for movable objects.
  145. template <typename IoObjectService>
  146. class basic_io_object<IoObjectService, true>
  147. {
  148. public:
  149. typedef IoObjectService service_type;
  150. typedef typename service_type::implementation_type implementation_type;
  151. asio::io_service& get_io_service()
  152. {
  153. return service_->get_io_service();
  154. }
  155. protected:
  156. explicit basic_io_object(asio::io_service& io_service)
  157. : service_(&asio::use_service<IoObjectService>(io_service))
  158. {
  159. service_->construct(implementation);
  160. }
  161. basic_io_object(basic_io_object&& other)
  162. : service_(&other.get_service())
  163. {
  164. service_->move_construct(implementation, other.implementation);
  165. }
  166. ~basic_io_object()
  167. {
  168. service_->destroy(implementation);
  169. }
  170. basic_io_object& operator=(basic_io_object&& other)
  171. {
  172. service_->move_assign(implementation,
  173. *other.service_, other.implementation);
  174. service_ = other.service_;
  175. return *this;
  176. }
  177. service_type& get_service()
  178. {
  179. return *service_;
  180. }
  181. const service_type& get_service() const
  182. {
  183. return *service_;
  184. }
  185. implementation_type& get_implementation()
  186. {
  187. return implementation;
  188. }
  189. const implementation_type& get_implementation() const
  190. {
  191. return implementation;
  192. }
  193. implementation_type implementation;
  194. private:
  195. basic_io_object(const basic_io_object&);
  196. void operator=(const basic_io_object&);
  197. IoObjectService* service_;
  198. };
  199. #endif // defined(ASIO_HAS_MOVE)
  200. } // namespace asio
  201. #include "asio/detail/pop_options.hpp"
  202. #endif // ASIO_BASIC_IO_OBJECT_HPP