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