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

source code of boost/libs/asio/include/boost/asio/basic_io_object.hpp