]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/basic_stream_file.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / asio / basic_stream_file.hpp
1 //
2 // basic_stream_file.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2022 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_STREAM_FILE_HPP
12 #define BOOST_ASIO_BASIC_STREAM_FILE_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
20 #if defined(BOOST_ASIO_HAS_FILE) \
21 || defined(GENERATING_DOCUMENTATION)
22
23 #include <cstddef>
24 #include <boost/asio/async_result.hpp>
25 #include <boost/asio/basic_file.hpp>
26 #include <boost/asio/detail/handler_type_requirements.hpp>
27 #include <boost/asio/detail/non_const_lvalue.hpp>
28 #include <boost/asio/detail/throw_error.hpp>
29 #include <boost/asio/error.hpp>
30
31 #include <boost/asio/detail/push_options.hpp>
32
33 namespace boost {
34 namespace asio {
35
36 #if !defined(BOOST_ASIO_BASIC_STREAM_FILE_FWD_DECL)
37 #define BOOST_ASIO_BASIC_STREAM_FILE_FWD_DECL
38
39 // Forward declaration with defaulted arguments.
40 template <typename Executor = any_io_executor>
41 class basic_stream_file;
42
43 #endif // !defined(BOOST_ASIO_BASIC_STREAM_FILE_FWD_DECL)
44
45 /// Provides stream-oriented file functionality.
46 /**
47 * The basic_stream_file class template provides asynchronous and blocking
48 * stream-oriented file functionality.
49 *
50 * @par Thread Safety
51 * @e Distinct @e objects: Safe.@n
52 * @e Shared @e objects: Unsafe.
53 *
54 * @par Concepts:
55 * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
56 */
57 template <typename Executor>
58 class basic_stream_file
59 : public basic_file<Executor>
60 {
61 public:
62 /// The type of the executor associated with the object.
63 typedef Executor executor_type;
64
65 /// Rebinds the file type to another executor.
66 template <typename Executor1>
67 struct rebind_executor
68 {
69 /// The file type when rebound to the specified executor.
70 typedef basic_stream_file<Executor1> other;
71 };
72
73 /// The native representation of a file.
74 #if defined(GENERATING_DOCUMENTATION)
75 typedef implementation_defined native_handle_type;
76 #else
77 typedef typename basic_file<Executor>::native_handle_type native_handle_type;
78 #endif
79
80 /// Construct a basic_stream_file without opening it.
81 /**
82 * This constructor initialises a file without opening it. The file needs to
83 * be opened before data can be read from or or written to it.
84 *
85 * @param ex The I/O executor that the file will use, by default, to
86 * dispatch handlers for any asynchronous operations performed on the file.
87 */
88 explicit basic_stream_file(const executor_type& ex)
89 : basic_file<Executor>(ex)
90 {
91 this->impl_.get_service().set_is_stream(
92 this->impl_.get_implementation(), true);
93 }
94
95 /// Construct a basic_stream_file without opening it.
96 /**
97 * This constructor initialises a file without opening it. The file needs to
98 * be opened before data can be read from or or written to it.
99 *
100 * @param context An execution context which provides the I/O executor that
101 * the file will use, by default, to dispatch handlers for any asynchronous
102 * operations performed on the file.
103 */
104 template <typename ExecutionContext>
105 explicit basic_stream_file(ExecutionContext& context,
106 typename constraint<
107 is_convertible<ExecutionContext&, execution_context&>::value,
108 defaulted_constraint
109 >::type = defaulted_constraint())
110 : basic_file<Executor>(context)
111 {
112 this->impl_.get_service().set_is_stream(
113 this->impl_.get_implementation(), true);
114 }
115
116 /// Construct and open a basic_stream_file.
117 /**
118 * This constructor initialises and opens a file.
119 *
120 * @param ex The I/O executor that the file will use, by default, to
121 * dispatch handlers for any asynchronous operations performed on the file.
122 *
123 * @param path The path name identifying the file to be opened.
124 *
125 * @param open_flags A set of flags that determine how the file should be
126 * opened.
127 *
128 * @throws boost::system::system_error Thrown on failure.
129 */
130 basic_stream_file(const executor_type& ex,
131 const char* path, file_base::flags open_flags)
132 : basic_file<Executor>(ex)
133 {
134 boost::system::error_code ec;
135 this->impl_.get_service().set_is_stream(
136 this->impl_.get_implementation(), true);
137 this->impl_.get_service().open(
138 this->impl_.get_implementation(),
139 path, open_flags, ec);
140 boost::asio::detail::throw_error(ec, "open");
141 }
142
143 /// Construct and open a basic_stream_file.
144 /**
145 * This constructor initialises and opens a file.
146 *
147 * @param context An execution context which provides the I/O executor that
148 * the file will use, by default, to dispatch handlers for any asynchronous
149 * operations performed on the file.
150 *
151 * @param path The path name identifying the file to be opened.
152 *
153 * @param open_flags A set of flags that determine how the file should be
154 * opened.
155 *
156 * @throws boost::system::system_error Thrown on failure.
157 */
158 template <typename ExecutionContext>
159 basic_stream_file(ExecutionContext& context,
160 const char* path, file_base::flags open_flags,
161 typename constraint<
162 is_convertible<ExecutionContext&, execution_context&>::value,
163 defaulted_constraint
164 >::type = defaulted_constraint())
165 : basic_file<Executor>(context)
166 {
167 boost::system::error_code ec;
168 this->impl_.get_service().set_is_stream(
169 this->impl_.get_implementation(), true);
170 this->impl_.get_service().open(
171 this->impl_.get_implementation(),
172 path, open_flags, ec);
173 boost::asio::detail::throw_error(ec, "open");
174 }
175
176 /// Construct and open a basic_stream_file.
177 /**
178 * This constructor initialises and opens a file.
179 *
180 * @param ex The I/O executor that the file will use, by default, to
181 * dispatch handlers for any asynchronous operations performed on the file.
182 *
183 * @param path The path name identifying the file to be opened.
184 *
185 * @param open_flags A set of flags that determine how the file should be
186 * opened.
187 *
188 * @throws boost::system::system_error Thrown on failure.
189 */
190 basic_stream_file(const executor_type& ex,
191 const std::string& path, file_base::flags open_flags)
192 : basic_file<Executor>(ex)
193 {
194 boost::system::error_code ec;
195 this->impl_.get_service().set_is_stream(
196 this->impl_.get_implementation(), true);
197 this->impl_.get_service().open(
198 this->impl_.get_implementation(),
199 path.c_str(), open_flags, ec);
200 boost::asio::detail::throw_error(ec, "open");
201 }
202
203 /// Construct and open a basic_stream_file.
204 /**
205 * This constructor initialises and opens a file.
206 *
207 * @param context An execution context which provides the I/O executor that
208 * the file will use, by default, to dispatch handlers for any asynchronous
209 * operations performed on the file.
210 *
211 * @param path The path name identifying the file to be opened.
212 *
213 * @param open_flags A set of flags that determine how the file should be
214 * opened.
215 *
216 * @throws boost::system::system_error Thrown on failure.
217 */
218 template <typename ExecutionContext>
219 basic_stream_file(ExecutionContext& context,
220 const std::string& path, file_base::flags open_flags,
221 typename constraint<
222 is_convertible<ExecutionContext&, execution_context&>::value,
223 defaulted_constraint
224 >::type = defaulted_constraint())
225 : basic_file<Executor>(context)
226 {
227 boost::system::error_code ec;
228 this->impl_.get_service().set_is_stream(
229 this->impl_.get_implementation(), true);
230 this->impl_.get_service().open(
231 this->impl_.get_implementation(),
232 path.c_str(), open_flags, ec);
233 boost::asio::detail::throw_error(ec, "open");
234 }
235
236 /// Construct a basic_stream_file on an existing native file.
237 /**
238 * This constructor initialises a stream file object to hold an existing
239 * native file.
240 *
241 * @param ex The I/O executor that the file will use, by default, to
242 * dispatch handlers for any asynchronous operations performed on the file.
243 *
244 * @param native_file The new underlying file implementation.
245 *
246 * @throws boost::system::system_error Thrown on failure.
247 */
248 basic_stream_file(const executor_type& ex,
249 const native_handle_type& native_file)
250 : basic_file<Executor>(ex, native_file)
251 {
252 this->impl_.get_service().set_is_stream(
253 this->impl_.get_implementation(), true);
254 }
255
256 /// Construct a basic_stream_file on an existing native file.
257 /**
258 * This constructor initialises a stream file object to hold an existing
259 * native file.
260 *
261 * @param context An execution context which provides the I/O executor that
262 * the file will use, by default, to dispatch handlers for any asynchronous
263 * operations performed on the file.
264 *
265 * @param native_file The new underlying file implementation.
266 *
267 * @throws boost::system::system_error Thrown on failure.
268 */
269 template <typename ExecutionContext>
270 basic_stream_file(ExecutionContext& context,
271 const native_handle_type& native_file,
272 typename constraint<
273 is_convertible<ExecutionContext&, execution_context&>::value,
274 defaulted_constraint
275 >::type = defaulted_constraint())
276 : basic_file<Executor>(context, native_file)
277 {
278 this->impl_.get_service().set_is_stream(
279 this->impl_.get_implementation(), true);
280 }
281
282 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
283 /// Move-construct a basic_stream_file from another.
284 /**
285 * This constructor moves a stream file from one object to another.
286 *
287 * @param other The other basic_stream_file object from which the move
288 * will occur.
289 *
290 * @note Following the move, the moved-from object is in the same state as if
291 * constructed using the @c basic_stream_file(const executor_type&)
292 * constructor.
293 */
294 basic_stream_file(basic_stream_file&& other) BOOST_ASIO_NOEXCEPT
295 : basic_file<Executor>(std::move(other))
296 {
297 }
298
299 /// Move-assign a basic_stream_file from another.
300 /**
301 * This assignment operator moves a stream file from one object to another.
302 *
303 * @param other The other basic_stream_file object from which the move
304 * will occur.
305 *
306 * @note Following the move, the moved-from object is in the same state as if
307 * constructed using the @c basic_stream_file(const executor_type&)
308 * constructor.
309 */
310 basic_stream_file& operator=(basic_stream_file&& other)
311 {
312 basic_file<Executor>::operator=(std::move(other));
313 return *this;
314 }
315
316 /// Move-construct a basic_stream_file from a file of another executor
317 /// type.
318 /**
319 * This constructor moves a stream file from one object to another.
320 *
321 * @param other The other basic_stream_file object from which the move
322 * will occur.
323 *
324 * @note Following the move, the moved-from object is in the same state as if
325 * constructed using the @c basic_stream_file(const executor_type&)
326 * constructor.
327 */
328 template <typename Executor1>
329 basic_stream_file(basic_stream_file<Executor1>&& other,
330 typename constraint<
331 is_convertible<Executor1, Executor>::value,
332 defaulted_constraint
333 >::type = defaulted_constraint())
334 : basic_file<Executor>(std::move(other))
335 {
336 }
337
338 /// Move-assign a basic_stream_file from a file of another executor type.
339 /**
340 * This assignment operator moves a stream file from one object to another.
341 *
342 * @param other The other basic_stream_file object from which the move
343 * will occur.
344 *
345 * @note Following the move, the moved-from object is in the same state as if
346 * constructed using the @c basic_stream_file(const executor_type&)
347 * constructor.
348 */
349 template <typename Executor1>
350 typename constraint<
351 is_convertible<Executor1, Executor>::value,
352 basic_stream_file&
353 >::type operator=(basic_stream_file<Executor1>&& other)
354 {
355 basic_file<Executor>::operator=(std::move(other));
356 return *this;
357 }
358 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
359
360 /// Destroys the file.
361 /**
362 * This function destroys the file, cancelling any outstanding asynchronous
363 * operations associated with the file as if by calling @c cancel.
364 */
365 ~basic_stream_file()
366 {
367 }
368
369 /// Seek to a position in the file.
370 /**
371 * This function updates the current position in the file.
372 *
373 * @param offset The requested position in the file, relative to @c whence.
374 *
375 * @param whence One of @c seek_set, @c seek_cur or @c seek_end.
376 *
377 * @returns The new position relative to the beginning of the file.
378 *
379 * @throws boost::system::system_error Thrown on failure.
380 */
381 uint64_t seek(int64_t offset, file_base::seek_basis whence)
382 {
383 boost::system::error_code ec;
384 uint64_t n = this->impl_.get_service().seek(
385 this->impl_.get_implementation(), offset, whence, ec);
386 boost::asio::detail::throw_error(ec, "seek");
387 return n;
388 }
389
390 /// Seek to a position in the file.
391 /**
392 * This function updates the current position in the file.
393 *
394 * @param offset The requested position in the file, relative to @c whence.
395 *
396 * @param whence One of @c seek_set, @c seek_cur or @c seek_end.
397 *
398 * @param ec Set to indicate what error occurred, if any.
399 *
400 * @returns The new position relative to the beginning of the file.
401 */
402 uint64_t seek(int64_t offset, file_base::seek_basis whence,
403 boost::system::error_code& ec)
404 {
405 return this->impl_.get_service().seek(
406 this->impl_.get_implementation(), offset, whence, ec);
407 }
408
409 /// Write some data to the file.
410 /**
411 * This function is used to write data to the stream file. The function call
412 * will block until one or more bytes of the data has been written
413 * successfully, or until an error occurs.
414 *
415 * @param buffers One or more data buffers to be written to the file.
416 *
417 * @returns The number of bytes written.
418 *
419 * @throws boost::system::system_error Thrown on failure. An error code of
420 * boost::asio::error::eof indicates that the end of the file was reached.
421 *
422 * @note The write_some operation may not transmit all of the data to the
423 * peer. Consider using the @ref write function if you need to ensure that
424 * all data is written before the blocking operation completes.
425 *
426 * @par Example
427 * To write a single data buffer use the @ref buffer function as follows:
428 * @code
429 * file.write_some(boost::asio::buffer(data, size));
430 * @endcode
431 * See the @ref buffer documentation for information on writing multiple
432 * buffers in one go, and how to use it with arrays, boost::array or
433 * std::vector.
434 */
435 template <typename ConstBufferSequence>
436 std::size_t write_some(const ConstBufferSequence& buffers)
437 {
438 boost::system::error_code ec;
439 std::size_t s = this->impl_.get_service().write_some(
440 this->impl_.get_implementation(), buffers, ec);
441 boost::asio::detail::throw_error(ec, "write_some");
442 return s;
443 }
444
445 /// Write some data to the file.
446 /**
447 * This function is used to write data to the stream file. The function call
448 * will block until one or more bytes of the data has been written
449 * successfully, or until an error occurs.
450 *
451 * @param buffers One or more data buffers to be written to the file.
452 *
453 * @param ec Set to indicate what error occurred, if any.
454 *
455 * @returns The number of bytes written. Returns 0 if an error occurred.
456 *
457 * @note The write_some operation may not transmit all of the data to the
458 * peer. Consider using the @ref write function if you need to ensure that
459 * all data is written before the blocking operation completes.
460 */
461 template <typename ConstBufferSequence>
462 std::size_t write_some(const ConstBufferSequence& buffers,
463 boost::system::error_code& ec)
464 {
465 return this->impl_.get_service().write_some(
466 this->impl_.get_implementation(), buffers, ec);
467 }
468
469 /// Start an asynchronous write.
470 /**
471 * This function is used to asynchronously write data to the stream file.
472 * It is an initiating function for an @ref asynchronous_operation, and always
473 * returns immediately.
474 *
475 * @param buffers One or more data buffers to be written to the file.
476 * Although the buffers object may be copied as necessary, ownership of the
477 * underlying memory blocks is retained by the caller, which must guarantee
478 * that they remain valid until the completion handler is called.
479 *
480 * @param token The @ref completion_token that will be used to produce a
481 * completion handler, which will be called when the write completes.
482 * Potential completion tokens include @ref use_future, @ref use_awaitable,
483 * @ref yield_context, or a function object with the correct completion
484 * signature. The function signature of the completion handler must be:
485 * @code void handler(
486 * const boost::system::error_code& error, // Result of operation.
487 * std::size_t bytes_transferred // Number of bytes written.
488 * ); @endcode
489 * Regardless of whether the asynchronous operation completes immediately or
490 * not, the completion handler will not be invoked from within this function.
491 * On immediate completion, invocation of the handler will be performed in a
492 * manner equivalent to using boost::asio::post().
493 *
494 * @par Completion Signature
495 * @code void(boost::system::error_code, std::size_t) @endcode
496 *
497 * @note The write operation may not transmit all of the data to the peer.
498 * Consider using the @ref async_write function if you need to ensure that all
499 * data is written before the asynchronous operation completes.
500 *
501 * @par Example
502 * To write a single data buffer use the @ref buffer function as follows:
503 * @code
504 * file.async_write_some(boost::asio::buffer(data, size), handler);
505 * @endcode
506 * See the @ref buffer documentation for information on writing multiple
507 * buffers in one go, and how to use it with arrays, boost::array or
508 * std::vector.
509 *
510 * @par Per-Operation Cancellation
511 * On POSIX or Windows operating systems, this asynchronous operation supports
512 * cancellation for the following boost::asio::cancellation_type values:
513 *
514 * @li @c cancellation_type::terminal
515 *
516 * @li @c cancellation_type::partial
517 *
518 * @li @c cancellation_type::total
519 */
520 template <typename ConstBufferSequence,
521 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
522 std::size_t)) WriteToken
523 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
524 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteToken,
525 void (boost::system::error_code, std::size_t))
526 async_write_some(const ConstBufferSequence& buffers,
527 BOOST_ASIO_MOVE_ARG(WriteToken) token
528 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
529 {
530 return async_initiate<WriteToken,
531 void (boost::system::error_code, std::size_t)>(
532 initiate_async_write_some(this), token, buffers);
533 }
534
535 /// Read some data from the file.
536 /**
537 * This function is used to read data from the stream file. The function
538 * call will block until one or more bytes of data has been read successfully,
539 * or until an error occurs.
540 *
541 * @param buffers One or more buffers into which the data will be read.
542 *
543 * @returns The number of bytes read.
544 *
545 * @throws boost::system::system_error Thrown on failure. An error code of
546 * boost::asio::error::eof indicates that the end of the file was reached.
547 *
548 * @note The read_some operation may not read all of the requested number of
549 * bytes. Consider using the @ref read function if you need to ensure that
550 * the requested amount of data is read before the blocking operation
551 * completes.
552 *
553 * @par Example
554 * To read into a single data buffer use the @ref buffer function as follows:
555 * @code
556 * file.read_some(boost::asio::buffer(data, size));
557 * @endcode
558 * See the @ref buffer documentation for information on reading into multiple
559 * buffers in one go, and how to use it with arrays, boost::array or
560 * std::vector.
561 */
562 template <typename MutableBufferSequence>
563 std::size_t read_some(const MutableBufferSequence& buffers)
564 {
565 boost::system::error_code ec;
566 std::size_t s = this->impl_.get_service().read_some(
567 this->impl_.get_implementation(), buffers, ec);
568 boost::asio::detail::throw_error(ec, "read_some");
569 return s;
570 }
571
572 /// Read some data from the file.
573 /**
574 * This function is used to read data from the stream file. The function
575 * call will block until one or more bytes of data has been read successfully,
576 * or until an error occurs.
577 *
578 * @param buffers One or more buffers into which the data will be read.
579 *
580 * @param ec Set to indicate what error occurred, if any.
581 *
582 * @returns The number of bytes read. Returns 0 if an error occurred.
583 *
584 * @note The read_some operation may not read all of the requested number of
585 * bytes. Consider using the @ref read function if you need to ensure that
586 * the requested amount of data is read before the blocking operation
587 * completes.
588 */
589 template <typename MutableBufferSequence>
590 std::size_t read_some(const MutableBufferSequence& buffers,
591 boost::system::error_code& ec)
592 {
593 return this->impl_.get_service().read_some(
594 this->impl_.get_implementation(), buffers, ec);
595 }
596
597 /// Start an asynchronous read.
598 /**
599 * This function is used to asynchronously read data from the stream file.
600 * It is an initiating function for an @ref asynchronous_operation, and always
601 * returns immediately.
602 *
603 * @param buffers One or more buffers into which the data will be read.
604 * Although the buffers object may be copied as necessary, ownership of the
605 * underlying memory blocks is retained by the caller, which must guarantee
606 * that they remain valid until the completion handler is called.
607 *
608 * @param token The @ref completion_token that will be used to produce a
609 * completion handler, which will be called when the read completes.
610 * Potential completion tokens include @ref use_future, @ref use_awaitable,
611 * @ref yield_context, or a function object with the correct completion
612 * signature. The function signature of the completion handler must be:
613 * @code void handler(
614 * const boost::system::error_code& error, // Result of operation.
615 * std::size_t bytes_transferred // Number of bytes read.
616 * ); @endcode
617 * Regardless of whether the asynchronous operation completes immediately or
618 * not, the completion handler will not be invoked from within this function.
619 * On immediate completion, invocation of the handler will be performed in a
620 * manner equivalent to using boost::asio::post().
621 *
622 * @par Completion Signature
623 * @code void(boost::system::error_code, std::size_t) @endcode
624 *
625 * @note The read operation may not read all of the requested number of bytes.
626 * Consider using the @ref async_read function if you need to ensure that the
627 * requested amount of data is read before the asynchronous operation
628 * completes.
629 *
630 * @par Example
631 * To read into a single data buffer use the @ref buffer function as follows:
632 * @code
633 * file.async_read_some(boost::asio::buffer(data, size), handler);
634 * @endcode
635 * See the @ref buffer documentation for information on reading into multiple
636 * buffers in one go, and how to use it with arrays, boost::array or
637 * std::vector.
638 *
639 * @par Per-Operation Cancellation
640 * On POSIX or Windows operating systems, this asynchronous operation supports
641 * cancellation for the following boost::asio::cancellation_type values:
642 *
643 * @li @c cancellation_type::terminal
644 *
645 * @li @c cancellation_type::partial
646 *
647 * @li @c cancellation_type::total
648 */
649 template <typename MutableBufferSequence,
650 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
651 std::size_t)) ReadToken
652 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
653 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken,
654 void (boost::system::error_code, std::size_t))
655 async_read_some(const MutableBufferSequence& buffers,
656 BOOST_ASIO_MOVE_ARG(ReadToken) token
657 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
658 {
659 return async_initiate<ReadToken,
660 void (boost::system::error_code, std::size_t)>(
661 initiate_async_read_some(this), token, buffers);
662 }
663
664 private:
665 // Disallow copying and assignment.
666 basic_stream_file(const basic_stream_file&) BOOST_ASIO_DELETED;
667 basic_stream_file& operator=(const basic_stream_file&) BOOST_ASIO_DELETED;
668
669 class initiate_async_write_some
670 {
671 public:
672 typedef Executor executor_type;
673
674 explicit initiate_async_write_some(basic_stream_file* self)
675 : self_(self)
676 {
677 }
678
679 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
680 {
681 return self_->get_executor();
682 }
683
684 template <typename WriteHandler, typename ConstBufferSequence>
685 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
686 const ConstBufferSequence& buffers) const
687 {
688 // If you get an error on the following line it means that your handler
689 // does not meet the documented type requirements for a WriteHandler.
690 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
691
692 detail::non_const_lvalue<WriteHandler> handler2(handler);
693 self_->impl_.get_service().async_write_some(
694 self_->impl_.get_implementation(), buffers,
695 handler2.value, self_->impl_.get_executor());
696 }
697
698 private:
699 basic_stream_file* self_;
700 };
701
702 class initiate_async_read_some
703 {
704 public:
705 typedef Executor executor_type;
706
707 explicit initiate_async_read_some(basic_stream_file* self)
708 : self_(self)
709 {
710 }
711
712 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
713 {
714 return self_->get_executor();
715 }
716
717 template <typename ReadHandler, typename MutableBufferSequence>
718 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
719 const MutableBufferSequence& buffers) const
720 {
721 // If you get an error on the following line it means that your handler
722 // does not meet the documented type requirements for a ReadHandler.
723 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
724
725 detail::non_const_lvalue<ReadHandler> handler2(handler);
726 self_->impl_.get_service().async_read_some(
727 self_->impl_.get_implementation(), buffers,
728 handler2.value, self_->impl_.get_executor());
729 }
730
731 private:
732 basic_stream_file* self_;
733 };
734 };
735
736 } // namespace asio
737 } // namespace boost
738
739 #include <boost/asio/detail/pop_options.hpp>
740
741 #endif // defined(BOOST_ASIO_HAS_FILE)
742 // || defined(GENERATING_DOCUMENTATION)
743
744 #endif // BOOST_ASIO_BASIC_STREAM_FILE_HPP