]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // basic_socket_acceptor.hpp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
5 | // Copyright (c) 2003-2016 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_SOCKET_ACCEPTOR_HPP | |
12 | #define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_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/basic_io_object.hpp> | |
20 | #include <boost/asio/basic_socket.hpp> | |
21 | #include <boost/asio/detail/handler_type_requirements.hpp> | |
22 | #include <boost/asio/detail/throw_error.hpp> | |
23 | #include <boost/asio/detail/type_traits.hpp> | |
24 | #include <boost/asio/error.hpp> | |
25 | #include <boost/asio/socket_acceptor_service.hpp> | |
26 | #include <boost/asio/socket_base.hpp> | |
27 | ||
28 | #include <boost/asio/detail/push_options.hpp> | |
29 | ||
30 | namespace boost { | |
31 | namespace asio { | |
32 | ||
33 | /// Provides the ability to accept new connections. | |
34 | /** | |
35 | * The basic_socket_acceptor class template is used for accepting new socket | |
36 | * connections. | |
37 | * | |
38 | * @par Thread Safety | |
39 | * @e Distinct @e objects: Safe.@n | |
40 | * @e Shared @e objects: Unsafe. | |
41 | * | |
42 | * @par Example | |
43 | * Opening a socket acceptor with the SO_REUSEADDR option enabled: | |
44 | * @code | |
45 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
46 | * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); | |
47 | * acceptor.open(endpoint.protocol()); | |
48 | * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); | |
49 | * acceptor.bind(endpoint); | |
50 | * acceptor.listen(); | |
51 | * @endcode | |
52 | */ | |
53 | template <typename Protocol, | |
54 | typename SocketAcceptorService = socket_acceptor_service<Protocol> > | |
55 | class basic_socket_acceptor | |
56 | : public basic_io_object<SocketAcceptorService>, | |
57 | public socket_base | |
58 | { | |
59 | public: | |
60 | /// (Deprecated: Use native_handle_type.) The native representation of an | |
61 | /// acceptor. | |
62 | typedef typename SocketAcceptorService::native_handle_type native_type; | |
63 | ||
64 | /// The native representation of an acceptor. | |
65 | typedef typename SocketAcceptorService::native_handle_type native_handle_type; | |
66 | ||
67 | /// The protocol type. | |
68 | typedef Protocol protocol_type; | |
69 | ||
70 | /// The endpoint type. | |
71 | typedef typename Protocol::endpoint endpoint_type; | |
72 | ||
73 | /// Construct an acceptor without opening it. | |
74 | /** | |
75 | * This constructor creates an acceptor without opening it to listen for new | |
76 | * connections. The open() function must be called before the acceptor can | |
77 | * accept new socket connections. | |
78 | * | |
79 | * @param io_service The io_service object that the acceptor will use to | |
80 | * dispatch handlers for any asynchronous operations performed on the | |
81 | * acceptor. | |
82 | */ | |
83 | explicit basic_socket_acceptor(boost::asio::io_service& io_service) | |
84 | : basic_io_object<SocketAcceptorService>(io_service) | |
85 | { | |
86 | } | |
87 | ||
88 | /// Construct an open acceptor. | |
89 | /** | |
90 | * This constructor creates an acceptor and automatically opens it. | |
91 | * | |
92 | * @param io_service The io_service object that the acceptor will use to | |
93 | * dispatch handlers for any asynchronous operations performed on the | |
94 | * acceptor. | |
95 | * | |
96 | * @param protocol An object specifying protocol parameters to be used. | |
97 | * | |
98 | * @throws boost::system::system_error Thrown on failure. | |
99 | */ | |
100 | basic_socket_acceptor(boost::asio::io_service& io_service, | |
101 | const protocol_type& protocol) | |
102 | : basic_io_object<SocketAcceptorService>(io_service) | |
103 | { | |
104 | boost::system::error_code ec; | |
105 | this->get_service().open(this->get_implementation(), protocol, ec); | |
106 | boost::asio::detail::throw_error(ec, "open"); | |
107 | } | |
108 | ||
109 | /// Construct an acceptor opened on the given endpoint. | |
110 | /** | |
111 | * This constructor creates an acceptor and automatically opens it to listen | |
112 | * for new connections on the specified endpoint. | |
113 | * | |
114 | * @param io_service The io_service object that the acceptor will use to | |
115 | * dispatch handlers for any asynchronous operations performed on the | |
116 | * acceptor. | |
117 | * | |
118 | * @param endpoint An endpoint on the local machine on which the acceptor | |
119 | * will listen for new connections. | |
120 | * | |
121 | * @param reuse_addr Whether the constructor should set the socket option | |
122 | * socket_base::reuse_address. | |
123 | * | |
124 | * @throws boost::system::system_error Thrown on failure. | |
125 | * | |
126 | * @note This constructor is equivalent to the following code: | |
127 | * @code | |
128 | * basic_socket_acceptor<Protocol> acceptor(io_service); | |
129 | * acceptor.open(endpoint.protocol()); | |
130 | * if (reuse_addr) | |
131 | * acceptor.set_option(socket_base::reuse_address(true)); | |
132 | * acceptor.bind(endpoint); | |
133 | * acceptor.listen(listen_backlog); | |
134 | * @endcode | |
135 | */ | |
136 | basic_socket_acceptor(boost::asio::io_service& io_service, | |
137 | const endpoint_type& endpoint, bool reuse_addr = true) | |
138 | : basic_io_object<SocketAcceptorService>(io_service) | |
139 | { | |
140 | boost::system::error_code ec; | |
141 | const protocol_type protocol = endpoint.protocol(); | |
142 | this->get_service().open(this->get_implementation(), protocol, ec); | |
143 | boost::asio::detail::throw_error(ec, "open"); | |
144 | if (reuse_addr) | |
145 | { | |
146 | this->get_service().set_option(this->get_implementation(), | |
147 | socket_base::reuse_address(true), ec); | |
148 | boost::asio::detail::throw_error(ec, "set_option"); | |
149 | } | |
150 | this->get_service().bind(this->get_implementation(), endpoint, ec); | |
151 | boost::asio::detail::throw_error(ec, "bind"); | |
152 | this->get_service().listen(this->get_implementation(), | |
153 | socket_base::max_connections, ec); | |
154 | boost::asio::detail::throw_error(ec, "listen"); | |
155 | } | |
156 | ||
157 | /// Construct a basic_socket_acceptor on an existing native acceptor. | |
158 | /** | |
159 | * This constructor creates an acceptor object to hold an existing native | |
160 | * acceptor. | |
161 | * | |
162 | * @param io_service The io_service object that the acceptor will use to | |
163 | * dispatch handlers for any asynchronous operations performed on the | |
164 | * acceptor. | |
165 | * | |
166 | * @param protocol An object specifying protocol parameters to be used. | |
167 | * | |
168 | * @param native_acceptor A native acceptor. | |
169 | * | |
170 | * @throws boost::system::system_error Thrown on failure. | |
171 | */ | |
172 | basic_socket_acceptor(boost::asio::io_service& io_service, | |
173 | const protocol_type& protocol, const native_handle_type& native_acceptor) | |
174 | : basic_io_object<SocketAcceptorService>(io_service) | |
175 | { | |
176 | boost::system::error_code ec; | |
177 | this->get_service().assign(this->get_implementation(), | |
178 | protocol, native_acceptor, ec); | |
179 | boost::asio::detail::throw_error(ec, "assign"); | |
180 | } | |
181 | ||
182 | #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
183 | /// Move-construct a basic_socket_acceptor from another. | |
184 | /** | |
185 | * This constructor moves an acceptor from one object to another. | |
186 | * | |
187 | * @param other The other basic_socket_acceptor object from which the move | |
188 | * will occur. | |
189 | * | |
190 | * @note Following the move, the moved-from object is in the same state as if | |
191 | * constructed using the @c basic_socket_acceptor(io_service&) constructor. | |
192 | */ | |
193 | basic_socket_acceptor(basic_socket_acceptor&& other) | |
194 | : basic_io_object<SocketAcceptorService>( | |
195 | BOOST_ASIO_MOVE_CAST(basic_socket_acceptor)(other)) | |
196 | { | |
197 | } | |
198 | ||
199 | /// Move-assign a basic_socket_acceptor from another. | |
200 | /** | |
201 | * This assignment operator moves an acceptor from one object to another. | |
202 | * | |
203 | * @param other The other basic_socket_acceptor object from which the move | |
204 | * will occur. | |
205 | * | |
206 | * @note Following the move, the moved-from object is in the same state as if | |
207 | * constructed using the @c basic_socket_acceptor(io_service&) constructor. | |
208 | */ | |
209 | basic_socket_acceptor& operator=(basic_socket_acceptor&& other) | |
210 | { | |
211 | basic_io_object<SocketAcceptorService>::operator=( | |
212 | BOOST_ASIO_MOVE_CAST(basic_socket_acceptor)(other)); | |
213 | return *this; | |
214 | } | |
215 | ||
216 | // All socket acceptors have access to each other's implementations. | |
217 | template <typename Protocol1, typename SocketAcceptorService1> | |
218 | friend class basic_socket_acceptor; | |
219 | ||
220 | /// Move-construct a basic_socket_acceptor from an acceptor of another | |
221 | /// protocol type. | |
222 | /** | |
223 | * This constructor moves an acceptor from one object to another. | |
224 | * | |
225 | * @param other The other basic_socket_acceptor object from which the move | |
226 | * will occur. | |
227 | * | |
228 | * @note Following the move, the moved-from object is in the same state as if | |
229 | * constructed using the @c basic_socket(io_service&) constructor. | |
230 | */ | |
231 | template <typename Protocol1, typename SocketAcceptorService1> | |
232 | basic_socket_acceptor( | |
233 | basic_socket_acceptor<Protocol1, SocketAcceptorService1>&& other, | |
234 | typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) | |
235 | : basic_io_object<SocketAcceptorService>(other.get_io_service()) | |
236 | { | |
237 | this->get_service().template converting_move_construct<Protocol1>( | |
238 | this->get_implementation(), other.get_implementation()); | |
239 | } | |
240 | ||
241 | /// Move-assign a basic_socket_acceptor from an acceptor of another protocol | |
242 | /// type. | |
243 | /** | |
244 | * This assignment operator moves an acceptor from one object to another. | |
245 | * | |
246 | * @param other The other basic_socket_acceptor object from which the move | |
247 | * will occur. | |
248 | * | |
249 | * @note Following the move, the moved-from object is in the same state as if | |
250 | * constructed using the @c basic_socket(io_service&) constructor. | |
251 | */ | |
252 | template <typename Protocol1, typename SocketAcceptorService1> | |
253 | typename enable_if<is_convertible<Protocol1, Protocol>::value, | |
254 | basic_socket_acceptor>::type& operator=( | |
255 | basic_socket_acceptor<Protocol1, SocketAcceptorService1>&& other) | |
256 | { | |
257 | basic_socket_acceptor tmp(BOOST_ASIO_MOVE_CAST2(basic_socket_acceptor< | |
258 | Protocol1, SocketAcceptorService1>)(other)); | |
259 | basic_io_object<SocketAcceptorService>::operator=( | |
260 | BOOST_ASIO_MOVE_CAST(basic_socket_acceptor)(tmp)); | |
261 | return *this; | |
262 | } | |
263 | #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
264 | ||
265 | /// Open the acceptor using the specified protocol. | |
266 | /** | |
267 | * This function opens the socket acceptor so that it will use the specified | |
268 | * protocol. | |
269 | * | |
270 | * @param protocol An object specifying which protocol is to be used. | |
271 | * | |
272 | * @throws boost::system::system_error Thrown on failure. | |
273 | * | |
274 | * @par Example | |
275 | * @code | |
276 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
277 | * acceptor.open(boost::asio::ip::tcp::v4()); | |
278 | * @endcode | |
279 | */ | |
280 | void open(const protocol_type& protocol = protocol_type()) | |
281 | { | |
282 | boost::system::error_code ec; | |
283 | this->get_service().open(this->get_implementation(), protocol, ec); | |
284 | boost::asio::detail::throw_error(ec, "open"); | |
285 | } | |
286 | ||
287 | /// Open the acceptor using the specified protocol. | |
288 | /** | |
289 | * This function opens the socket acceptor so that it will use the specified | |
290 | * protocol. | |
291 | * | |
292 | * @param protocol An object specifying which protocol is to be used. | |
293 | * | |
294 | * @param ec Set to indicate what error occurred, if any. | |
295 | * | |
296 | * @par Example | |
297 | * @code | |
298 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
299 | * boost::system::error_code ec; | |
300 | * acceptor.open(boost::asio::ip::tcp::v4(), ec); | |
301 | * if (ec) | |
302 | * { | |
303 | * // An error occurred. | |
304 | * } | |
305 | * @endcode | |
306 | */ | |
307 | boost::system::error_code open(const protocol_type& protocol, | |
308 | boost::system::error_code& ec) | |
309 | { | |
310 | return this->get_service().open(this->get_implementation(), protocol, ec); | |
311 | } | |
312 | ||
313 | /// Assigns an existing native acceptor to the acceptor. | |
314 | /* | |
315 | * This function opens the acceptor to hold an existing native acceptor. | |
316 | * | |
317 | * @param protocol An object specifying which protocol is to be used. | |
318 | * | |
319 | * @param native_acceptor A native acceptor. | |
320 | * | |
321 | * @throws boost::system::system_error Thrown on failure. | |
322 | */ | |
323 | void assign(const protocol_type& protocol, | |
324 | const native_handle_type& native_acceptor) | |
325 | { | |
326 | boost::system::error_code ec; | |
327 | this->get_service().assign(this->get_implementation(), | |
328 | protocol, native_acceptor, ec); | |
329 | boost::asio::detail::throw_error(ec, "assign"); | |
330 | } | |
331 | ||
332 | /// Assigns an existing native acceptor to the acceptor. | |
333 | /* | |
334 | * This function opens the acceptor to hold an existing native acceptor. | |
335 | * | |
336 | * @param protocol An object specifying which protocol is to be used. | |
337 | * | |
338 | * @param native_acceptor A native acceptor. | |
339 | * | |
340 | * @param ec Set to indicate what error occurred, if any. | |
341 | */ | |
342 | boost::system::error_code assign(const protocol_type& protocol, | |
343 | const native_handle_type& native_acceptor, boost::system::error_code& ec) | |
344 | { | |
345 | return this->get_service().assign(this->get_implementation(), | |
346 | protocol, native_acceptor, ec); | |
347 | } | |
348 | ||
349 | /// Determine whether the acceptor is open. | |
350 | bool is_open() const | |
351 | { | |
352 | return this->get_service().is_open(this->get_implementation()); | |
353 | } | |
354 | ||
355 | /// Bind the acceptor to the given local endpoint. | |
356 | /** | |
357 | * This function binds the socket acceptor to the specified endpoint on the | |
358 | * local machine. | |
359 | * | |
360 | * @param endpoint An endpoint on the local machine to which the socket | |
361 | * acceptor will be bound. | |
362 | * | |
363 | * @throws boost::system::system_error Thrown on failure. | |
364 | * | |
365 | * @par Example | |
366 | * @code | |
367 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
368 | * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); | |
369 | * acceptor.open(endpoint.protocol()); | |
370 | * acceptor.bind(endpoint); | |
371 | * @endcode | |
372 | */ | |
373 | void bind(const endpoint_type& endpoint) | |
374 | { | |
375 | boost::system::error_code ec; | |
376 | this->get_service().bind(this->get_implementation(), endpoint, ec); | |
377 | boost::asio::detail::throw_error(ec, "bind"); | |
378 | } | |
379 | ||
380 | /// Bind the acceptor to the given local endpoint. | |
381 | /** | |
382 | * This function binds the socket acceptor to the specified endpoint on the | |
383 | * local machine. | |
384 | * | |
385 | * @param endpoint An endpoint on the local machine to which the socket | |
386 | * acceptor will be bound. | |
387 | * | |
388 | * @param ec Set to indicate what error occurred, if any. | |
389 | * | |
390 | * @par Example | |
391 | * @code | |
392 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
393 | * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); | |
394 | * acceptor.open(endpoint.protocol()); | |
395 | * boost::system::error_code ec; | |
396 | * acceptor.bind(endpoint, ec); | |
397 | * if (ec) | |
398 | * { | |
399 | * // An error occurred. | |
400 | * } | |
401 | * @endcode | |
402 | */ | |
403 | boost::system::error_code bind(const endpoint_type& endpoint, | |
404 | boost::system::error_code& ec) | |
405 | { | |
406 | return this->get_service().bind(this->get_implementation(), endpoint, ec); | |
407 | } | |
408 | ||
409 | /// Place the acceptor into the state where it will listen for new | |
410 | /// connections. | |
411 | /** | |
412 | * This function puts the socket acceptor into the state where it may accept | |
413 | * new connections. | |
414 | * | |
415 | * @param backlog The maximum length of the queue of pending connections. | |
416 | * | |
417 | * @throws boost::system::system_error Thrown on failure. | |
418 | */ | |
419 | void listen(int backlog = socket_base::max_connections) | |
420 | { | |
421 | boost::system::error_code ec; | |
422 | this->get_service().listen(this->get_implementation(), backlog, ec); | |
423 | boost::asio::detail::throw_error(ec, "listen"); | |
424 | } | |
425 | ||
426 | /// Place the acceptor into the state where it will listen for new | |
427 | /// connections. | |
428 | /** | |
429 | * This function puts the socket acceptor into the state where it may accept | |
430 | * new connections. | |
431 | * | |
432 | * @param backlog The maximum length of the queue of pending connections. | |
433 | * | |
434 | * @param ec Set to indicate what error occurred, if any. | |
435 | * | |
436 | * @par Example | |
437 | * @code | |
438 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
439 | * ... | |
440 | * boost::system::error_code ec; | |
441 | * acceptor.listen(boost::asio::socket_base::max_connections, ec); | |
442 | * if (ec) | |
443 | * { | |
444 | * // An error occurred. | |
445 | * } | |
446 | * @endcode | |
447 | */ | |
448 | boost::system::error_code listen(int backlog, boost::system::error_code& ec) | |
449 | { | |
450 | return this->get_service().listen(this->get_implementation(), backlog, ec); | |
451 | } | |
452 | ||
453 | /// Close the acceptor. | |
454 | /** | |
455 | * This function is used to close the acceptor. Any asynchronous accept | |
456 | * operations will be cancelled immediately. | |
457 | * | |
458 | * A subsequent call to open() is required before the acceptor can again be | |
459 | * used to again perform socket accept operations. | |
460 | * | |
461 | * @throws boost::system::system_error Thrown on failure. | |
462 | */ | |
463 | void close() | |
464 | { | |
465 | boost::system::error_code ec; | |
466 | this->get_service().close(this->get_implementation(), ec); | |
467 | boost::asio::detail::throw_error(ec, "close"); | |
468 | } | |
469 | ||
470 | /// Close the acceptor. | |
471 | /** | |
472 | * This function is used to close the acceptor. Any asynchronous accept | |
473 | * operations will be cancelled immediately. | |
474 | * | |
475 | * A subsequent call to open() is required before the acceptor can again be | |
476 | * used to again perform socket accept operations. | |
477 | * | |
478 | * @param ec Set to indicate what error occurred, if any. | |
479 | * | |
480 | * @par Example | |
481 | * @code | |
482 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
483 | * ... | |
484 | * boost::system::error_code ec; | |
485 | * acceptor.close(ec); | |
486 | * if (ec) | |
487 | * { | |
488 | * // An error occurred. | |
489 | * } | |
490 | * @endcode | |
491 | */ | |
492 | boost::system::error_code close(boost::system::error_code& ec) | |
493 | { | |
494 | return this->get_service().close(this->get_implementation(), ec); | |
495 | } | |
496 | ||
497 | /// (Deprecated: Use native_handle().) Get the native acceptor representation. | |
498 | /** | |
499 | * This function may be used to obtain the underlying representation of the | |
500 | * acceptor. This is intended to allow access to native acceptor functionality | |
501 | * that is not otherwise provided. | |
502 | */ | |
503 | native_type native() | |
504 | { | |
505 | return this->get_service().native_handle(this->get_implementation()); | |
506 | } | |
507 | ||
508 | /// Get the native acceptor representation. | |
509 | /** | |
510 | * This function may be used to obtain the underlying representation of the | |
511 | * acceptor. This is intended to allow access to native acceptor functionality | |
512 | * that is not otherwise provided. | |
513 | */ | |
514 | native_handle_type native_handle() | |
515 | { | |
516 | return this->get_service().native_handle(this->get_implementation()); | |
517 | } | |
518 | ||
519 | /// Cancel all asynchronous operations associated with the acceptor. | |
520 | /** | |
521 | * This function causes all outstanding asynchronous connect, send and receive | |
522 | * operations to finish immediately, and the handlers for cancelled operations | |
523 | * will be passed the boost::asio::error::operation_aborted error. | |
524 | * | |
525 | * @throws boost::system::system_error Thrown on failure. | |
526 | */ | |
527 | void cancel() | |
528 | { | |
529 | boost::system::error_code ec; | |
530 | this->get_service().cancel(this->get_implementation(), ec); | |
531 | boost::asio::detail::throw_error(ec, "cancel"); | |
532 | } | |
533 | ||
534 | /// Cancel all asynchronous operations associated with the acceptor. | |
535 | /** | |
536 | * This function causes all outstanding asynchronous connect, send and receive | |
537 | * operations to finish immediately, and the handlers for cancelled operations | |
538 | * will be passed the boost::asio::error::operation_aborted error. | |
539 | * | |
540 | * @param ec Set to indicate what error occurred, if any. | |
541 | */ | |
542 | boost::system::error_code cancel(boost::system::error_code& ec) | |
543 | { | |
544 | return this->get_service().cancel(this->get_implementation(), ec); | |
545 | } | |
546 | ||
547 | /// Set an option on the acceptor. | |
548 | /** | |
549 | * This function is used to set an option on the acceptor. | |
550 | * | |
551 | * @param option The new option value to be set on the acceptor. | |
552 | * | |
553 | * @throws boost::system::system_error Thrown on failure. | |
554 | * | |
555 | * @sa SettableSocketOption @n | |
556 | * boost::asio::socket_base::reuse_address | |
557 | * boost::asio::socket_base::enable_connection_aborted | |
558 | * | |
559 | * @par Example | |
560 | * Setting the SOL_SOCKET/SO_REUSEADDR option: | |
561 | * @code | |
562 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
563 | * ... | |
564 | * boost::asio::ip::tcp::acceptor::reuse_address option(true); | |
565 | * acceptor.set_option(option); | |
566 | * @endcode | |
567 | */ | |
568 | template <typename SettableSocketOption> | |
569 | void set_option(const SettableSocketOption& option) | |
570 | { | |
571 | boost::system::error_code ec; | |
572 | this->get_service().set_option(this->get_implementation(), option, ec); | |
573 | boost::asio::detail::throw_error(ec, "set_option"); | |
574 | } | |
575 | ||
576 | /// Set an option on the acceptor. | |
577 | /** | |
578 | * This function is used to set an option on the acceptor. | |
579 | * | |
580 | * @param option The new option value to be set on the acceptor. | |
581 | * | |
582 | * @param ec Set to indicate what error occurred, if any. | |
583 | * | |
584 | * @sa SettableSocketOption @n | |
585 | * boost::asio::socket_base::reuse_address | |
586 | * boost::asio::socket_base::enable_connection_aborted | |
587 | * | |
588 | * @par Example | |
589 | * Setting the SOL_SOCKET/SO_REUSEADDR option: | |
590 | * @code | |
591 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
592 | * ... | |
593 | * boost::asio::ip::tcp::acceptor::reuse_address option(true); | |
594 | * boost::system::error_code ec; | |
595 | * acceptor.set_option(option, ec); | |
596 | * if (ec) | |
597 | * { | |
598 | * // An error occurred. | |
599 | * } | |
600 | * @endcode | |
601 | */ | |
602 | template <typename SettableSocketOption> | |
603 | boost::system::error_code set_option(const SettableSocketOption& option, | |
604 | boost::system::error_code& ec) | |
605 | { | |
606 | return this->get_service().set_option( | |
607 | this->get_implementation(), option, ec); | |
608 | } | |
609 | ||
610 | /// Get an option from the acceptor. | |
611 | /** | |
612 | * This function is used to get the current value of an option on the | |
613 | * acceptor. | |
614 | * | |
615 | * @param option The option value to be obtained from the acceptor. | |
616 | * | |
617 | * @throws boost::system::system_error Thrown on failure. | |
618 | * | |
619 | * @sa GettableSocketOption @n | |
620 | * boost::asio::socket_base::reuse_address | |
621 | * | |
622 | * @par Example | |
623 | * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: | |
624 | * @code | |
625 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
626 | * ... | |
627 | * boost::asio::ip::tcp::acceptor::reuse_address option; | |
628 | * acceptor.get_option(option); | |
629 | * bool is_set = option.get(); | |
630 | * @endcode | |
631 | */ | |
632 | template <typename GettableSocketOption> | |
633 | void get_option(GettableSocketOption& option) | |
634 | { | |
635 | boost::system::error_code ec; | |
636 | this->get_service().get_option(this->get_implementation(), option, ec); | |
637 | boost::asio::detail::throw_error(ec, "get_option"); | |
638 | } | |
639 | ||
640 | /// Get an option from the acceptor. | |
641 | /** | |
642 | * This function is used to get the current value of an option on the | |
643 | * acceptor. | |
644 | * | |
645 | * @param option The option value to be obtained from the acceptor. | |
646 | * | |
647 | * @param ec Set to indicate what error occurred, if any. | |
648 | * | |
649 | * @sa GettableSocketOption @n | |
650 | * boost::asio::socket_base::reuse_address | |
651 | * | |
652 | * @par Example | |
653 | * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: | |
654 | * @code | |
655 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
656 | * ... | |
657 | * boost::asio::ip::tcp::acceptor::reuse_address option; | |
658 | * boost::system::error_code ec; | |
659 | * acceptor.get_option(option, ec); | |
660 | * if (ec) | |
661 | * { | |
662 | * // An error occurred. | |
663 | * } | |
664 | * bool is_set = option.get(); | |
665 | * @endcode | |
666 | */ | |
667 | template <typename GettableSocketOption> | |
668 | boost::system::error_code get_option(GettableSocketOption& option, | |
669 | boost::system::error_code& ec) | |
670 | { | |
671 | return this->get_service().get_option( | |
672 | this->get_implementation(), option, ec); | |
673 | } | |
674 | ||
675 | /// Perform an IO control command on the acceptor. | |
676 | /** | |
677 | * This function is used to execute an IO control command on the acceptor. | |
678 | * | |
679 | * @param command The IO control command to be performed on the acceptor. | |
680 | * | |
681 | * @throws boost::system::system_error Thrown on failure. | |
682 | * | |
683 | * @sa IoControlCommand @n | |
684 | * boost::asio::socket_base::non_blocking_io | |
685 | * | |
686 | * @par Example | |
687 | * Getting the number of bytes ready to read: | |
688 | * @code | |
689 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
690 | * ... | |
691 | * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); | |
692 | * socket.io_control(command); | |
693 | * @endcode | |
694 | */ | |
695 | template <typename IoControlCommand> | |
696 | void io_control(IoControlCommand& command) | |
697 | { | |
698 | boost::system::error_code ec; | |
699 | this->get_service().io_control(this->get_implementation(), command, ec); | |
700 | boost::asio::detail::throw_error(ec, "io_control"); | |
701 | } | |
702 | ||
703 | /// Perform an IO control command on the acceptor. | |
704 | /** | |
705 | * This function is used to execute an IO control command on the acceptor. | |
706 | * | |
707 | * @param command The IO control command to be performed on the acceptor. | |
708 | * | |
709 | * @param ec Set to indicate what error occurred, if any. | |
710 | * | |
711 | * @sa IoControlCommand @n | |
712 | * boost::asio::socket_base::non_blocking_io | |
713 | * | |
714 | * @par Example | |
715 | * Getting the number of bytes ready to read: | |
716 | * @code | |
717 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
718 | * ... | |
719 | * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); | |
720 | * boost::system::error_code ec; | |
721 | * socket.io_control(command, ec); | |
722 | * if (ec) | |
723 | * { | |
724 | * // An error occurred. | |
725 | * } | |
726 | * @endcode | |
727 | */ | |
728 | template <typename IoControlCommand> | |
729 | boost::system::error_code io_control(IoControlCommand& command, | |
730 | boost::system::error_code& ec) | |
731 | { | |
732 | return this->get_service().io_control( | |
733 | this->get_implementation(), command, ec); | |
734 | } | |
735 | ||
736 | /// Gets the non-blocking mode of the acceptor. | |
737 | /** | |
738 | * @returns @c true if the acceptor's synchronous operations will fail with | |
739 | * boost::asio::error::would_block if they are unable to perform the requested | |
740 | * operation immediately. If @c false, synchronous operations will block | |
741 | * until complete. | |
742 | * | |
743 | * @note The non-blocking mode has no effect on the behaviour of asynchronous | |
744 | * operations. Asynchronous operations will never fail with the error | |
745 | * boost::asio::error::would_block. | |
746 | */ | |
747 | bool non_blocking() const | |
748 | { | |
749 | return this->get_service().non_blocking(this->get_implementation()); | |
750 | } | |
751 | ||
752 | /// Sets the non-blocking mode of the acceptor. | |
753 | /** | |
754 | * @param mode If @c true, the acceptor's synchronous operations will fail | |
755 | * with boost::asio::error::would_block if they are unable to perform the | |
756 | * requested operation immediately. If @c false, synchronous operations will | |
757 | * block until complete. | |
758 | * | |
759 | * @throws boost::system::system_error Thrown on failure. | |
760 | * | |
761 | * @note The non-blocking mode has no effect on the behaviour of asynchronous | |
762 | * operations. Asynchronous operations will never fail with the error | |
763 | * boost::asio::error::would_block. | |
764 | */ | |
765 | void non_blocking(bool mode) | |
766 | { | |
767 | boost::system::error_code ec; | |
768 | this->get_service().non_blocking(this->get_implementation(), mode, ec); | |
769 | boost::asio::detail::throw_error(ec, "non_blocking"); | |
770 | } | |
771 | ||
772 | /// Sets the non-blocking mode of the acceptor. | |
773 | /** | |
774 | * @param mode If @c true, the acceptor's synchronous operations will fail | |
775 | * with boost::asio::error::would_block if they are unable to perform the | |
776 | * requested operation immediately. If @c false, synchronous operations will | |
777 | * block until complete. | |
778 | * | |
779 | * @param ec Set to indicate what error occurred, if any. | |
780 | * | |
781 | * @note The non-blocking mode has no effect on the behaviour of asynchronous | |
782 | * operations. Asynchronous operations will never fail with the error | |
783 | * boost::asio::error::would_block. | |
784 | */ | |
785 | boost::system::error_code non_blocking( | |
786 | bool mode, boost::system::error_code& ec) | |
787 | { | |
788 | return this->get_service().non_blocking( | |
789 | this->get_implementation(), mode, ec); | |
790 | } | |
791 | ||
792 | /// Gets the non-blocking mode of the native acceptor implementation. | |
793 | /** | |
794 | * This function is used to retrieve the non-blocking mode of the underlying | |
795 | * native acceptor. This mode has no effect on the behaviour of the acceptor | |
796 | * object's synchronous operations. | |
797 | * | |
798 | * @returns @c true if the underlying acceptor is in non-blocking mode and | |
799 | * direct system calls may fail with boost::asio::error::would_block (or the | |
800 | * equivalent system error). | |
801 | * | |
802 | * @note The current non-blocking mode is cached by the acceptor object. | |
803 | * Consequently, the return value may be incorrect if the non-blocking mode | |
804 | * was set directly on the native acceptor. | |
805 | */ | |
806 | bool native_non_blocking() const | |
807 | { | |
808 | return this->get_service().native_non_blocking(this->get_implementation()); | |
809 | } | |
810 | ||
811 | /// Sets the non-blocking mode of the native acceptor implementation. | |
812 | /** | |
813 | * This function is used to modify the non-blocking mode of the underlying | |
814 | * native acceptor. It has no effect on the behaviour of the acceptor object's | |
815 | * synchronous operations. | |
816 | * | |
817 | * @param mode If @c true, the underlying acceptor is put into non-blocking | |
818 | * mode and direct system calls may fail with boost::asio::error::would_block | |
819 | * (or the equivalent system error). | |
820 | * | |
821 | * @throws boost::system::system_error Thrown on failure. If the @c mode is | |
822 | * @c false, but the current value of @c non_blocking() is @c true, this | |
823 | * function fails with boost::asio::error::invalid_argument, as the | |
824 | * combination does not make sense. | |
825 | */ | |
826 | void native_non_blocking(bool mode) | |
827 | { | |
828 | boost::system::error_code ec; | |
829 | this->get_service().native_non_blocking( | |
830 | this->get_implementation(), mode, ec); | |
831 | boost::asio::detail::throw_error(ec, "native_non_blocking"); | |
832 | } | |
833 | ||
834 | /// Sets the non-blocking mode of the native acceptor implementation. | |
835 | /** | |
836 | * This function is used to modify the non-blocking mode of the underlying | |
837 | * native acceptor. It has no effect on the behaviour of the acceptor object's | |
838 | * synchronous operations. | |
839 | * | |
840 | * @param mode If @c true, the underlying acceptor is put into non-blocking | |
841 | * mode and direct system calls may fail with boost::asio::error::would_block | |
842 | * (or the equivalent system error). | |
843 | * | |
844 | * @param ec Set to indicate what error occurred, if any. If the @c mode is | |
845 | * @c false, but the current value of @c non_blocking() is @c true, this | |
846 | * function fails with boost::asio::error::invalid_argument, as the | |
847 | * combination does not make sense. | |
848 | */ | |
849 | boost::system::error_code native_non_blocking( | |
850 | bool mode, boost::system::error_code& ec) | |
851 | { | |
852 | return this->get_service().native_non_blocking( | |
853 | this->get_implementation(), mode, ec); | |
854 | } | |
855 | ||
856 | /// Get the local endpoint of the acceptor. | |
857 | /** | |
858 | * This function is used to obtain the locally bound endpoint of the acceptor. | |
859 | * | |
860 | * @returns An object that represents the local endpoint of the acceptor. | |
861 | * | |
862 | * @throws boost::system::system_error Thrown on failure. | |
863 | * | |
864 | * @par Example | |
865 | * @code | |
866 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
867 | * ... | |
868 | * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); | |
869 | * @endcode | |
870 | */ | |
871 | endpoint_type local_endpoint() const | |
872 | { | |
873 | boost::system::error_code ec; | |
874 | endpoint_type ep = this->get_service().local_endpoint( | |
875 | this->get_implementation(), ec); | |
876 | boost::asio::detail::throw_error(ec, "local_endpoint"); | |
877 | return ep; | |
878 | } | |
879 | ||
880 | /// Get the local endpoint of the acceptor. | |
881 | /** | |
882 | * This function is used to obtain the locally bound endpoint of the acceptor. | |
883 | * | |
884 | * @param ec Set to indicate what error occurred, if any. | |
885 | * | |
886 | * @returns An object that represents the local endpoint of the acceptor. | |
887 | * Returns a default-constructed endpoint object if an error occurred and the | |
888 | * error handler did not throw an exception. | |
889 | * | |
890 | * @par Example | |
891 | * @code | |
892 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
893 | * ... | |
894 | * boost::system::error_code ec; | |
895 | * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); | |
896 | * if (ec) | |
897 | * { | |
898 | * // An error occurred. | |
899 | * } | |
900 | * @endcode | |
901 | */ | |
902 | endpoint_type local_endpoint(boost::system::error_code& ec) const | |
903 | { | |
904 | return this->get_service().local_endpoint(this->get_implementation(), ec); | |
905 | } | |
906 | ||
907 | /// Accept a new connection. | |
908 | /** | |
909 | * This function is used to accept a new connection from a peer into the | |
910 | * given socket. The function call will block until a new connection has been | |
911 | * accepted successfully or an error occurs. | |
912 | * | |
913 | * @param peer The socket into which the new connection will be accepted. | |
914 | * | |
915 | * @throws boost::system::system_error Thrown on failure. | |
916 | * | |
917 | * @par Example | |
918 | * @code | |
919 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
920 | * ... | |
921 | * boost::asio::ip::tcp::socket socket(io_service); | |
922 | * acceptor.accept(socket); | |
923 | * @endcode | |
924 | */ | |
925 | template <typename Protocol1, typename SocketService> | |
926 | void accept(basic_socket<Protocol1, SocketService>& peer, | |
927 | typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) | |
928 | { | |
929 | boost::system::error_code ec; | |
930 | this->get_service().accept(this->get_implementation(), | |
931 | peer, static_cast<endpoint_type*>(0), ec); | |
932 | boost::asio::detail::throw_error(ec, "accept"); | |
933 | } | |
934 | ||
935 | /// Accept a new connection. | |
936 | /** | |
937 | * This function is used to accept a new connection from a peer into the | |
938 | * given socket. The function call will block until a new connection has been | |
939 | * accepted successfully or an error occurs. | |
940 | * | |
941 | * @param peer The socket into which the new connection will be accepted. | |
942 | * | |
943 | * @param ec Set to indicate what error occurred, if any. | |
944 | * | |
945 | * @par Example | |
946 | * @code | |
947 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
948 | * ... | |
949 | * boost::asio::ip::tcp::soocket socket(io_service); | |
950 | * boost::system::error_code ec; | |
951 | * acceptor.accept(socket, ec); | |
952 | * if (ec) | |
953 | * { | |
954 | * // An error occurred. | |
955 | * } | |
956 | * @endcode | |
957 | */ | |
958 | template <typename Protocol1, typename SocketService> | |
959 | boost::system::error_code accept( | |
960 | basic_socket<Protocol1, SocketService>& peer, | |
961 | boost::system::error_code& ec, | |
962 | typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) | |
963 | { | |
964 | return this->get_service().accept(this->get_implementation(), | |
965 | peer, static_cast<endpoint_type*>(0), ec); | |
966 | } | |
967 | ||
968 | /// Start an asynchronous accept. | |
969 | /** | |
970 | * This function is used to asynchronously accept a new connection into a | |
971 | * socket. The function call always returns immediately. | |
972 | * | |
973 | * @param peer The socket into which the new connection will be accepted. | |
974 | * Ownership of the peer object is retained by the caller, which must | |
975 | * guarantee that it is valid until the handler is called. | |
976 | * | |
977 | * @param handler The handler to be called when the accept operation | |
978 | * completes. Copies will be made of the handler as required. The function | |
979 | * signature of the handler must be: | |
980 | * @code void handler( | |
981 | * const boost::system::error_code& error // Result of operation. | |
982 | * ); @endcode | |
983 | * Regardless of whether the asynchronous operation completes immediately or | |
984 | * not, the handler will not be invoked from within this function. Invocation | |
985 | * of the handler will be performed in a manner equivalent to using | |
986 | * boost::asio::io_service::post(). | |
987 | * | |
988 | * @par Example | |
989 | * @code | |
990 | * void accept_handler(const boost::system::error_code& error) | |
991 | * { | |
992 | * if (!error) | |
993 | * { | |
994 | * // Accept succeeded. | |
995 | * } | |
996 | * } | |
997 | * | |
998 | * ... | |
999 | * | |
1000 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
1001 | * ... | |
1002 | * boost::asio::ip::tcp::socket socket(io_service); | |
1003 | * acceptor.async_accept(socket, accept_handler); | |
1004 | * @endcode | |
1005 | */ | |
1006 | template <typename Protocol1, typename SocketService, typename AcceptHandler> | |
1007 | BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, | |
1008 | void (boost::system::error_code)) | |
1009 | async_accept(basic_socket<Protocol1, SocketService>& peer, | |
1010 | BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, | |
1011 | typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) | |
1012 | { | |
1013 | // If you get an error on the following line it means that your handler does | |
1014 | // not meet the documented type requirements for a AcceptHandler. | |
1015 | BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; | |
1016 | ||
1017 | return this->get_service().async_accept(this->get_implementation(), | |
1018 | peer, static_cast<endpoint_type*>(0), | |
1019 | BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); | |
1020 | } | |
1021 | ||
1022 | /// Accept a new connection and obtain the endpoint of the peer | |
1023 | /** | |
1024 | * This function is used to accept a new connection from a peer into the | |
1025 | * given socket, and additionally provide the endpoint of the remote peer. | |
1026 | * The function call will block until a new connection has been accepted | |
1027 | * successfully or an error occurs. | |
1028 | * | |
1029 | * @param peer The socket into which the new connection will be accepted. | |
1030 | * | |
1031 | * @param peer_endpoint An endpoint object which will receive the endpoint of | |
1032 | * the remote peer. | |
1033 | * | |
1034 | * @throws boost::system::system_error Thrown on failure. | |
1035 | * | |
1036 | * @par Example | |
1037 | * @code | |
1038 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
1039 | * ... | |
1040 | * boost::asio::ip::tcp::socket socket(io_service); | |
1041 | * boost::asio::ip::tcp::endpoint endpoint; | |
1042 | * acceptor.accept(socket, endpoint); | |
1043 | * @endcode | |
1044 | */ | |
1045 | template <typename SocketService> | |
1046 | void accept(basic_socket<protocol_type, SocketService>& peer, | |
1047 | endpoint_type& peer_endpoint) | |
1048 | { | |
1049 | boost::system::error_code ec; | |
1050 | this->get_service().accept(this->get_implementation(), | |
1051 | peer, &peer_endpoint, ec); | |
1052 | boost::asio::detail::throw_error(ec, "accept"); | |
1053 | } | |
1054 | ||
1055 | /// Accept a new connection and obtain the endpoint of the peer | |
1056 | /** | |
1057 | * This function is used to accept a new connection from a peer into the | |
1058 | * given socket, and additionally provide the endpoint of the remote peer. | |
1059 | * The function call will block until a new connection has been accepted | |
1060 | * successfully or an error occurs. | |
1061 | * | |
1062 | * @param peer The socket into which the new connection will be accepted. | |
1063 | * | |
1064 | * @param peer_endpoint An endpoint object which will receive the endpoint of | |
1065 | * the remote peer. | |
1066 | * | |
1067 | * @param ec Set to indicate what error occurred, if any. | |
1068 | * | |
1069 | * @par Example | |
1070 | * @code | |
1071 | * boost::asio::ip::tcp::acceptor acceptor(io_service); | |
1072 | * ... | |
1073 | * boost::asio::ip::tcp::socket socket(io_service); | |
1074 | * boost::asio::ip::tcp::endpoint endpoint; | |
1075 | * boost::system::error_code ec; | |
1076 | * acceptor.accept(socket, endpoint, ec); | |
1077 | * if (ec) | |
1078 | * { | |
1079 | * // An error occurred. | |
1080 | * } | |
1081 | * @endcode | |
1082 | */ | |
1083 | template <typename SocketService> | |
1084 | boost::system::error_code accept( | |
1085 | basic_socket<protocol_type, SocketService>& peer, | |
1086 | endpoint_type& peer_endpoint, boost::system::error_code& ec) | |
1087 | { | |
1088 | return this->get_service().accept( | |
1089 | this->get_implementation(), peer, &peer_endpoint, ec); | |
1090 | } | |
1091 | ||
1092 | /// Start an asynchronous accept. | |
1093 | /** | |
1094 | * This function is used to asynchronously accept a new connection into a | |
1095 | * socket, and additionally obtain the endpoint of the remote peer. The | |
1096 | * function call always returns immediately. | |
1097 | * | |
1098 | * @param peer The socket into which the new connection will be accepted. | |
1099 | * Ownership of the peer object is retained by the caller, which must | |
1100 | * guarantee that it is valid until the handler is called. | |
1101 | * | |
1102 | * @param peer_endpoint An endpoint object into which the endpoint of the | |
1103 | * remote peer will be written. Ownership of the peer_endpoint object is | |
1104 | * retained by the caller, which must guarantee that it is valid until the | |
1105 | * handler is called. | |
1106 | * | |
1107 | * @param handler The handler to be called when the accept operation | |
1108 | * completes. Copies will be made of the handler as required. The function | |
1109 | * signature of the handler must be: | |
1110 | * @code void handler( | |
1111 | * const boost::system::error_code& error // Result of operation. | |
1112 | * ); @endcode | |
1113 | * Regardless of whether the asynchronous operation completes immediately or | |
1114 | * not, the handler will not be invoked from within this function. Invocation | |
1115 | * of the handler will be performed in a manner equivalent to using | |
1116 | * boost::asio::io_service::post(). | |
1117 | */ | |
1118 | template <typename SocketService, typename AcceptHandler> | |
1119 | BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, | |
1120 | void (boost::system::error_code)) | |
1121 | async_accept(basic_socket<protocol_type, SocketService>& peer, | |
1122 | endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) | |
1123 | { | |
1124 | // If you get an error on the following line it means that your handler does | |
1125 | // not meet the documented type requirements for a AcceptHandler. | |
1126 | BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; | |
1127 | ||
1128 | return this->get_service().async_accept(this->get_implementation(), peer, | |
1129 | &peer_endpoint, BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); | |
1130 | } | |
1131 | }; | |
1132 | ||
1133 | } // namespace asio | |
1134 | } // namespace boost | |
1135 | ||
1136 | #include <boost/asio/detail/pop_options.hpp> | |
1137 | ||
1138 | #endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP |