Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 08:29:08

0001 //
0002 // basic_file.hpp
0003 // ~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_BASIC_FILE_HPP
0012 #define BOOST_ASIO_BASIC_FILE_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 
0020 #if defined(BOOST_ASIO_HAS_FILE) \
0021   || defined(GENERATING_DOCUMENTATION)
0022 
0023 #include <string>
0024 #include <utility>
0025 #include <boost/asio/any_io_executor.hpp>
0026 #include <boost/asio/async_result.hpp>
0027 #include <boost/asio/detail/cstdint.hpp>
0028 #include <boost/asio/detail/handler_type_requirements.hpp>
0029 #include <boost/asio/detail/io_object_impl.hpp>
0030 #include <boost/asio/detail/non_const_lvalue.hpp>
0031 #include <boost/asio/detail/throw_error.hpp>
0032 #include <boost/asio/detail/type_traits.hpp>
0033 #include <boost/asio/error.hpp>
0034 #include <boost/asio/execution_context.hpp>
0035 #include <boost/asio/post.hpp>
0036 #include <boost/asio/file_base.hpp>
0037 #if defined(BOOST_ASIO_HAS_IOCP)
0038 # include <boost/asio/detail/win_iocp_file_service.hpp>
0039 #elif defined(BOOST_ASIO_HAS_IO_URING)
0040 # include <boost/asio/detail/io_uring_file_service.hpp>
0041 #endif
0042 
0043 #include <boost/asio/detail/push_options.hpp>
0044 
0045 namespace boost {
0046 namespace asio {
0047 
0048 #if !defined(BOOST_ASIO_BASIC_FILE_FWD_DECL)
0049 #define BOOST_ASIO_BASIC_FILE_FWD_DECL
0050 
0051 // Forward declaration with defaulted arguments.
0052 template <typename Executor = any_io_executor>
0053 class basic_file;
0054 
0055 #endif // !defined(BOOST_ASIO_BASIC_FILE_FWD_DECL)
0056 
0057 /// Provides file functionality.
0058 /**
0059  * The basic_file class template provides functionality that is common to both
0060  * stream-oriented and random-access files.
0061  *
0062  * @par Thread Safety
0063  * @e Distinct @e objects: Safe.@n
0064  * @e Shared @e objects: Unsafe.
0065  */
0066 template <typename Executor>
0067 class basic_file
0068   : public file_base
0069 {
0070 public:
0071   /// The type of the executor associated with the object.
0072   typedef Executor executor_type;
0073 
0074   /// Rebinds the file type to another executor.
0075   template <typename Executor1>
0076   struct rebind_executor
0077   {
0078     /// The file type when rebound to the specified executor.
0079     typedef basic_file<Executor1> other;
0080   };
0081 
0082   /// The native representation of a file.
0083 #if defined(GENERATING_DOCUMENTATION)
0084   typedef implementation_defined native_handle_type;
0085 #elif defined(BOOST_ASIO_HAS_IOCP)
0086   typedef detail::win_iocp_file_service::native_handle_type native_handle_type;
0087 #elif defined(BOOST_ASIO_HAS_IO_URING)
0088   typedef detail::io_uring_file_service::native_handle_type native_handle_type;
0089 #endif
0090 
0091   /// Construct a basic_file without opening it.
0092   /**
0093    * This constructor initialises a file without opening it.
0094    *
0095    * @param ex The I/O executor that the file will use, by default, to
0096    * dispatch handlers for any asynchronous operations performed on the file.
0097    */
0098   explicit basic_file(const executor_type& ex)
0099     : impl_(0, ex)
0100   {
0101   }
0102 
0103   /// Construct a basic_file without opening it.
0104   /**
0105    * This constructor initialises a file without opening it.
0106    *
0107    * @param context An execution context which provides the I/O executor that
0108    * the file will use, by default, to dispatch handlers for any asynchronous
0109    * operations performed on the file.
0110    */
0111   template <typename ExecutionContext>
0112   explicit basic_file(ExecutionContext& context,
0113       constraint_t<
0114         is_convertible<ExecutionContext&, execution_context&>::value,
0115         defaulted_constraint
0116       > = defaulted_constraint())
0117     : impl_(0, 0, context)
0118   {
0119   }
0120 
0121   /// Construct and open a basic_file.
0122   /**
0123    * This constructor initialises a file and opens it.
0124    *
0125    * @param ex The I/O executor that the file will use, by default, to
0126    * dispatch handlers for any asynchronous operations performed on the file.
0127    *
0128    * @param path The path name identifying the file to be opened.
0129    *
0130    * @param open_flags A set of flags that determine how the file should be
0131    * opened.
0132    *
0133    * Exactly one of the following file_base::flags values must be specified:
0134    *
0135    * @li flags::read_only
0136    * @li flags::write_only
0137    * @li flags::read_write
0138    *
0139    * The following flags may be bitwise or-ed in addition:
0140    *
0141    * @li flags::append
0142    * @li flags::create
0143    * @li flags::exclusive
0144    * @li flags::truncate
0145    * @li flags::sync_all_on_write
0146    */
0147   explicit basic_file(const executor_type& ex,
0148       const char* path, file_base::flags open_flags)
0149     : impl_(0, ex)
0150   {
0151     boost::system::error_code ec;
0152     impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
0153     boost::asio::detail::throw_error(ec, "open");
0154   }
0155 
0156   /// Construct and open a basic_file.
0157   /**
0158    * This constructor initialises a file and opens it.
0159    *
0160    * @param context An execution context which provides the I/O executor that
0161    * the file will use, by default, to dispatch handlers for any asynchronous
0162    * operations performed on the file.
0163    *
0164    * @param path The path name identifying the file to be opened.
0165    *
0166    * @param open_flags A set of flags that determine how the file should be
0167    * opened.
0168    *
0169    * Exactly one of the following file_base::flags values must be specified:
0170    *
0171    * @li flags::read_only
0172    * @li flags::write_only
0173    * @li flags::read_write
0174    *
0175    * The following flags may be bitwise or-ed in addition:
0176    *
0177    * @li flags::append
0178    * @li flags::create
0179    * @li flags::exclusive
0180    * @li flags::truncate
0181    * @li flags::sync_all_on_write
0182    */
0183   template <typename ExecutionContext>
0184   explicit basic_file(ExecutionContext& context,
0185       const char* path, file_base::flags open_flags,
0186       constraint_t<
0187         is_convertible<ExecutionContext&, execution_context&>::value,
0188         defaulted_constraint
0189       > = defaulted_constraint())
0190     : impl_(0, 0, context)
0191   {
0192     boost::system::error_code ec;
0193     impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
0194     boost::asio::detail::throw_error(ec, "open");
0195   }
0196 
0197   /// Construct and open a basic_file.
0198   /**
0199    * This constructor initialises a file and opens it.
0200    *
0201    * @param ex The I/O executor that the file will use, by default, to
0202    * dispatch handlers for any asynchronous operations performed on the file.
0203    *
0204    * @param path The path name identifying the file to be opened.
0205    *
0206    * @param open_flags A set of flags that determine how the file should be
0207    * opened.
0208    *
0209    * Exactly one of the following file_base::flags values must be specified:
0210    *
0211    * @li flags::read_only
0212    * @li flags::write_only
0213    * @li flags::read_write
0214    *
0215    * The following flags may be bitwise or-ed in addition:
0216    *
0217    * @li flags::append
0218    * @li flags::create
0219    * @li flags::exclusive
0220    * @li flags::truncate
0221    * @li flags::sync_all_on_write
0222    */
0223   explicit basic_file(const executor_type& ex,
0224       const std::string& path, file_base::flags open_flags)
0225     : impl_(0, ex)
0226   {
0227     boost::system::error_code ec;
0228     impl_.get_service().open(impl_.get_implementation(),
0229         path.c_str(), open_flags, ec);
0230     boost::asio::detail::throw_error(ec, "open");
0231   }
0232 
0233   /// Construct and open a basic_file.
0234   /**
0235    * This constructor initialises a file and opens it.
0236    *
0237    * @param context An execution context which provides the I/O executor that
0238    * the file will use, by default, to dispatch handlers for any asynchronous
0239    * operations performed on the file.
0240    *
0241    * @param path The path name identifying the file to be opened.
0242    *
0243    * @param open_flags A set of flags that determine how the file should be
0244    * opened.
0245    *
0246    * Exactly one of the following file_base::flags values must be specified:
0247    *
0248    * @li flags::read_only
0249    * @li flags::write_only
0250    * @li flags::read_write
0251    *
0252    * The following flags may be bitwise or-ed in addition:
0253    *
0254    * @li flags::append
0255    * @li flags::create
0256    * @li flags::exclusive
0257    * @li flags::truncate
0258    * @li flags::sync_all_on_write
0259    */
0260   template <typename ExecutionContext>
0261   explicit basic_file(ExecutionContext& context,
0262       const std::string& path, file_base::flags open_flags,
0263       constraint_t<
0264         is_convertible<ExecutionContext&, execution_context&>::value,
0265         defaulted_constraint
0266       > = defaulted_constraint())
0267     : impl_(0, 0, context)
0268   {
0269     boost::system::error_code ec;
0270     impl_.get_service().open(impl_.get_implementation(),
0271         path.c_str(), open_flags, ec);
0272     boost::asio::detail::throw_error(ec, "open");
0273   }
0274 
0275   /// Construct a basic_file on an existing native file handle.
0276   /**
0277    * This constructor initialises a file object to hold an existing native file.
0278    *
0279    * @param ex The I/O executor that the file will use, by default, to
0280    * dispatch handlers for any asynchronous operations performed on the file.
0281    *
0282    * @param native_file A native file handle.
0283    *
0284    * @throws boost::system::system_error Thrown on failure.
0285    */
0286   basic_file(const executor_type& ex, const native_handle_type& native_file)
0287     : impl_(0, ex)
0288   {
0289     boost::system::error_code ec;
0290     impl_.get_service().assign(
0291         impl_.get_implementation(), native_file, ec);
0292     boost::asio::detail::throw_error(ec, "assign");
0293   }
0294 
0295   /// Construct a basic_file on an existing native file.
0296   /**
0297    * This constructor initialises a file object to hold an existing native file.
0298    *
0299    * @param context An execution context which provides the I/O executor that
0300    * the file will use, by default, to dispatch handlers for any asynchronous
0301    * operations performed on the file.
0302    *
0303    * @param native_file A native file.
0304    *
0305    * @throws boost::system::system_error Thrown on failure.
0306    */
0307   template <typename ExecutionContext>
0308   basic_file(ExecutionContext& context, const native_handle_type& native_file,
0309       constraint_t<
0310         is_convertible<ExecutionContext&, execution_context&>::value,
0311         defaulted_constraint
0312       > = defaulted_constraint())
0313     : impl_(0, 0, context)
0314   {
0315     boost::system::error_code ec;
0316     impl_.get_service().assign(
0317         impl_.get_implementation(), native_file, ec);
0318     boost::asio::detail::throw_error(ec, "assign");
0319   }
0320 
0321   /// Move-construct a basic_file from another.
0322   /**
0323    * This constructor moves a file from one object to another.
0324    *
0325    * @param other The other basic_file object from which the move will
0326    * occur.
0327    *
0328    * @note Following the move, the moved-from object is in the same state as if
0329    * constructed using the @c basic_file(const executor_type&) constructor.
0330    */
0331   basic_file(basic_file&& other) noexcept
0332     : impl_(std::move(other.impl_))
0333   {
0334   }
0335 
0336   /// Move-assign a basic_file from another.
0337   /**
0338    * This assignment operator moves a file from one object to another.
0339    *
0340    * @param other The other basic_file object from which the move will
0341    * occur.
0342    *
0343    * @note Following the move, the moved-from object is in the same state as if
0344    * constructed using the @c basic_file(const executor_type&) constructor.
0345    */
0346   basic_file& operator=(basic_file&& other)
0347   {
0348     impl_ = std::move(other.impl_);
0349     return *this;
0350   }
0351 
0352   // All files have access to each other's implementations.
0353   template <typename Executor1>
0354   friend class basic_file;
0355 
0356   /// Move-construct a basic_file from a file of another executor type.
0357   /**
0358    * This constructor moves a file from one object to another.
0359    *
0360    * @param other The other basic_file object from which the move will
0361    * occur.
0362    *
0363    * @note Following the move, the moved-from object is in the same state as if
0364    * constructed using the @c basic_file(const executor_type&) constructor.
0365    */
0366   template <typename Executor1>
0367   basic_file(basic_file<Executor1>&& other,
0368       constraint_t<
0369         is_convertible<Executor1, Executor>::value,
0370         defaulted_constraint
0371       > = defaulted_constraint())
0372     : impl_(std::move(other.impl_))
0373   {
0374   }
0375 
0376   /// Move-assign a basic_file from a file of another executor type.
0377   /**
0378    * This assignment operator moves a file from one object to another.
0379    *
0380    * @param other The other basic_file object from which the move will
0381    * occur.
0382    *
0383    * @note Following the move, the moved-from object is in the same state as if
0384    * constructed using the @c basic_file(const executor_type&) constructor.
0385    */
0386   template <typename Executor1>
0387   constraint_t<
0388     is_convertible<Executor1, Executor>::value,
0389     basic_file&
0390   > operator=(basic_file<Executor1>&& other)
0391   {
0392     basic_file tmp(std::move(other));
0393     impl_ = std::move(tmp.impl_);
0394     return *this;
0395   }
0396 
0397   /// Get the executor associated with the object.
0398   const executor_type& get_executor() noexcept
0399   {
0400     return impl_.get_executor();
0401   }
0402 
0403   /// Open the file using the specified path.
0404   /**
0405    * This function opens the file so that it will use the specified path.
0406    *
0407    * @param path The path name identifying the file to be opened.
0408    *
0409    * @param open_flags A set of flags that determine how the file should be
0410    * opened.
0411    *
0412    * @throws boost::system::system_error Thrown on failure.
0413    *
0414    * Exactly one of the following file_base::flags values must be specified:
0415    *
0416    * @li flags::read_only
0417    * @li flags::write_only
0418    * @li flags::read_write
0419    *
0420    * The following flags may be bitwise or-ed in addition:
0421    *
0422    * @li flags::append
0423    * @li flags::create
0424    * @li flags::exclusive
0425    * @li flags::truncate
0426    * @li flags::sync_all_on_write
0427    *
0428    * @par Example
0429    * @code
0430    * boost::asio::stream_file file(my_context);
0431    * file.open("/path/to/my/file", boost::asio::stream_file::read_only);
0432    * @endcode
0433    */
0434   void open(const char* path, file_base::flags open_flags)
0435   {
0436     boost::system::error_code ec;
0437     impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
0438     boost::asio::detail::throw_error(ec, "open");
0439   }
0440 
0441   /// Open the file using the specified path.
0442   /**
0443    * This function opens the file so that it will use the specified path.
0444    *
0445    * @param path The path name identifying the file to be opened.
0446    *
0447    * @param open_flags A set of flags that determine how the file should be
0448    * opened.
0449    *
0450    * Exactly one of the following file_base::flags values must be specified:
0451    *
0452    * @li flags::read_only
0453    * @li flags::write_only
0454    * @li flags::read_write
0455    *
0456    * The following flags may be bitwise or-ed in addition:
0457    *
0458    * @li flags::append
0459    * @li flags::create
0460    * @li flags::exclusive
0461    * @li flags::truncate
0462    * @li flags::sync_all_on_write
0463    *
0464    * @param ec Set to indicate what error occurred, if any.
0465    *
0466    * @par Example
0467    * @code
0468    * boost::asio::stream_file file(my_context);
0469    * boost::system::error_code ec;
0470    * file.open("/path/to/my/file", boost::asio::stream_file::read_only, ec);
0471    * if (ec)
0472    * {
0473    *   // An error occurred.
0474    * }
0475    * @endcode
0476    */
0477   BOOST_ASIO_SYNC_OP_VOID open(const char* path,
0478       file_base::flags open_flags, boost::system::error_code& ec)
0479   {
0480     impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
0481     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0482   }
0483 
0484   /// Open the file using the specified path.
0485   /**
0486    * This function opens the file so that it will use the specified path.
0487    *
0488    * @param path The path name identifying the file to be opened.
0489    *
0490    * @param open_flags A set of flags that determine how the file should be
0491    * opened.
0492    *
0493    * @throws boost::system::system_error Thrown on failure.
0494    *
0495    * Exactly one of the following file_base::flags values must be specified:
0496    *
0497    * @li flags::read_only
0498    * @li flags::write_only
0499    * @li flags::read_write
0500    *
0501    * The following flags may be bitwise or-ed in addition:
0502    *
0503    * @li flags::append
0504    * @li flags::create
0505    * @li flags::exclusive
0506    * @li flags::truncate
0507    * @li flags::sync_all_on_write
0508    *
0509    * @par Example
0510    * @code
0511    * boost::asio::stream_file file(my_context);
0512    * file.open("/path/to/my/file", boost::asio::stream_file::read_only);
0513    * @endcode
0514    */
0515   void open(const std::string& path, file_base::flags open_flags)
0516   {
0517     boost::system::error_code ec;
0518     impl_.get_service().open(impl_.get_implementation(),
0519         path.c_str(), open_flags, ec);
0520     boost::asio::detail::throw_error(ec, "open");
0521   }
0522 
0523   /// Open the file using the specified path.
0524   /**
0525    * This function opens the file so that it will use the specified path.
0526    *
0527    * @param path The path name identifying the file to be opened.
0528    *
0529    * @param open_flags A set of flags that determine how the file should be
0530    * opened.
0531    *
0532    * @param ec Set to indicate what error occurred, if any.
0533    *
0534    * Exactly one of the following file_base::flags values must be specified:
0535    *
0536    * @li flags::read_only
0537    * @li flags::write_only
0538    * @li flags::read_write
0539    *
0540    * The following flags may be bitwise or-ed in addition:
0541    *
0542    * @li flags::append
0543    * @li flags::create
0544    * @li flags::exclusive
0545    * @li flags::truncate
0546    * @li flags::sync_all_on_write
0547    *
0548    * @par Example
0549    * @code
0550    * boost::asio::stream_file file(my_context);
0551    * boost::system::error_code ec;
0552    * file.open("/path/to/my/file", boost::asio::stream_file::read_only, ec);
0553    * if (ec)
0554    * {
0555    *   // An error occurred.
0556    * }
0557    * @endcode
0558    */
0559   BOOST_ASIO_SYNC_OP_VOID open(const std::string& path,
0560       file_base::flags open_flags, boost::system::error_code& ec)
0561   {
0562     impl_.get_service().open(impl_.get_implementation(),
0563         path.c_str(), open_flags, ec);
0564     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0565   }
0566 
0567   /// Assign an existing native file to the file.
0568   /*
0569    * This function opens the file to hold an existing native file.
0570    *
0571    * @param native_file A native file.
0572    *
0573    * @throws boost::system::system_error Thrown on failure.
0574    */
0575   void assign(const native_handle_type& native_file)
0576   {
0577     boost::system::error_code ec;
0578     impl_.get_service().assign(
0579         impl_.get_implementation(), native_file, ec);
0580     boost::asio::detail::throw_error(ec, "assign");
0581   }
0582 
0583   /// Assign an existing native file to the file.
0584   /*
0585    * This function opens the file to hold an existing native file.
0586    *
0587    * @param native_file A native file.
0588    *
0589    * @param ec Set to indicate what error occurred, if any.
0590    */
0591   BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_file,
0592       boost::system::error_code& ec)
0593   {
0594     impl_.get_service().assign(
0595         impl_.get_implementation(), native_file, ec);
0596     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0597   }
0598 
0599   /// Determine whether the file is open.
0600   bool is_open() const
0601   {
0602     return impl_.get_service().is_open(impl_.get_implementation());
0603   }
0604 
0605   /// Close the file.
0606   /**
0607    * This function is used to close the file. Any asynchronous read or write
0608    * operations will be cancelled immediately, and will complete with the
0609    * boost::asio::error::operation_aborted error.
0610    *
0611    * @throws boost::system::system_error Thrown on failure. Note that, even if
0612    * the function indicates an error, the underlying descriptor is closed.
0613    */
0614   void close()
0615   {
0616     boost::system::error_code ec;
0617     impl_.get_service().close(impl_.get_implementation(), ec);
0618     boost::asio::detail::throw_error(ec, "close");
0619   }
0620 
0621   /// Close the file.
0622   /**
0623    * This function is used to close the file. Any asynchronous read or write
0624    * operations will be cancelled immediately, and will complete with the
0625    * boost::asio::error::operation_aborted error.
0626    *
0627    * @param ec Set to indicate what error occurred, if any. Note that, even if
0628    * the function indicates an error, the underlying descriptor is closed.
0629    *
0630    * @par Example
0631    * @code
0632    * boost::asio::stream_file file(my_context);
0633    * ...
0634    * boost::system::error_code ec;
0635    * file.close(ec);
0636    * if (ec)
0637    * {
0638    *   // An error occurred.
0639    * }
0640    * @endcode
0641    */
0642   BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
0643   {
0644     impl_.get_service().close(impl_.get_implementation(), ec);
0645     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0646   }
0647 
0648   /// Release ownership of the underlying native file.
0649   /**
0650    * This function causes all outstanding asynchronous read and write
0651    * operations to finish immediately, and the handlers for cancelled
0652    * operations will be passed the boost::asio::error::operation_aborted error.
0653    * Ownership of the native file is then transferred to the caller.
0654    *
0655    * @throws boost::system::system_error Thrown on failure.
0656    *
0657    * @note This function is unsupported on Windows versions prior to Windows
0658    * 8.1, and will fail with boost::asio::error::operation_not_supported on
0659    * these platforms.
0660    */
0661 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
0662   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
0663   __declspec(deprecated("This function always fails with "
0664         "operation_not_supported when used on Windows versions "
0665         "prior to Windows 8.1."))
0666 #endif
0667   native_handle_type release()
0668   {
0669     boost::system::error_code ec;
0670     native_handle_type s = impl_.get_service().release(
0671         impl_.get_implementation(), ec);
0672     boost::asio::detail::throw_error(ec, "release");
0673     return s;
0674   }
0675 
0676   /// Release ownership of the underlying native file.
0677   /**
0678    * This function causes all outstanding asynchronous read and write
0679    * operations to finish immediately, and the handlers for cancelled
0680    * operations will be passed the boost::asio::error::operation_aborted error.
0681    * Ownership of the native file is then transferred to the caller.
0682    *
0683    * @param ec Set to indicate what error occurred, if any.
0684    *
0685    * @note This function is unsupported on Windows versions prior to Windows
0686    * 8.1, and will fail with boost::asio::error::operation_not_supported on
0687    * these platforms.
0688    */
0689 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
0690   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
0691   __declspec(deprecated("This function always fails with "
0692         "operation_not_supported when used on Windows versions "
0693         "prior to Windows 8.1."))
0694 #endif
0695   native_handle_type release(boost::system::error_code& ec)
0696   {
0697     return impl_.get_service().release(impl_.get_implementation(), ec);
0698   }
0699 
0700   /// Get the native file representation.
0701   /**
0702    * This function may be used to obtain the underlying representation of the
0703    * file. This is intended to allow access to native file functionality
0704    * that is not otherwise provided.
0705    */
0706   native_handle_type native_handle()
0707   {
0708     return impl_.get_service().native_handle(impl_.get_implementation());
0709   }
0710 
0711   /// Cancel all asynchronous operations associated with the file.
0712   /**
0713    * This function causes all outstanding asynchronous read and write
0714    * operations to finish immediately, and the handlers for cancelled
0715    * operations will be passed the boost::asio::error::operation_aborted error.
0716    *
0717    * @throws boost::system::system_error Thrown on failure.
0718    *
0719    * @note Calls to cancel() will always fail with
0720    * boost::asio::error::operation_not_supported when run on Windows XP, Windows
0721    * Server 2003, and earlier versions of Windows, unless
0722    * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
0723    * two issues that should be considered before enabling its use:
0724    *
0725    * @li It will only cancel asynchronous operations that were initiated in the
0726    * current thread.
0727    *
0728    * @li It can appear to complete without error, but the request to cancel the
0729    * unfinished operations may be silently ignored by the operating system.
0730    * Whether it works or not seems to depend on the drivers that are installed.
0731    *
0732    * For portable cancellation, consider using the close() function to
0733    * simultaneously cancel the outstanding operations and close the file.
0734    *
0735    * When running on Windows Vista, Windows Server 2008, and later, the
0736    * CancelIoEx function is always used. This function does not have the
0737    * problems described above.
0738    */
0739 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
0740   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
0741   && !defined(BOOST_ASIO_ENABLE_CANCELIO)
0742   __declspec(deprecated("By default, this function always fails with "
0743         "operation_not_supported when used on Windows XP, Windows Server 2003, "
0744         "or earlier. Consult documentation for details."))
0745 #endif
0746   void cancel()
0747   {
0748     boost::system::error_code ec;
0749     impl_.get_service().cancel(impl_.get_implementation(), ec);
0750     boost::asio::detail::throw_error(ec, "cancel");
0751   }
0752 
0753   /// Cancel all asynchronous operations associated with the file.
0754   /**
0755    * This function causes all outstanding asynchronous read and write
0756    * operations to finish immediately, and the handlers for cancelled
0757    * operations will be passed the boost::asio::error::operation_aborted error.
0758    *
0759    * @param ec Set to indicate what error occurred, if any.
0760    *
0761    * @note Calls to cancel() will always fail with
0762    * boost::asio::error::operation_not_supported when run on Windows XP, Windows
0763    * Server 2003, and earlier versions of Windows, unless
0764    * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
0765    * two issues that should be considered before enabling its use:
0766    *
0767    * @li It will only cancel asynchronous operations that were initiated in the
0768    * current thread.
0769    *
0770    * @li It can appear to complete without error, but the request to cancel the
0771    * unfinished operations may be silently ignored by the operating system.
0772    * Whether it works or not seems to depend on the drivers that are installed.
0773    *
0774    * For portable cancellation, consider using the close() function to
0775    * simultaneously cancel the outstanding operations and close the file.
0776    *
0777    * When running on Windows Vista, Windows Server 2008, and later, the
0778    * CancelIoEx function is always used. This function does not have the
0779    * problems described above.
0780    */
0781 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
0782   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
0783   && !defined(BOOST_ASIO_ENABLE_CANCELIO)
0784   __declspec(deprecated("By default, this function always fails with "
0785         "operation_not_supported when used on Windows XP, Windows Server 2003, "
0786         "or earlier. Consult documentation for details."))
0787 #endif
0788   BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
0789   {
0790     impl_.get_service().cancel(impl_.get_implementation(), ec);
0791     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0792   }
0793 
0794   /// Get the size of the file.
0795   /**
0796    * This function determines the size of the file, in bytes.
0797    *
0798    * @throws boost::system::system_error Thrown on failure.
0799    */
0800   uint64_t size() const
0801   {
0802     boost::system::error_code ec;
0803     uint64_t s = impl_.get_service().size(impl_.get_implementation(), ec);
0804     boost::asio::detail::throw_error(ec, "size");
0805     return s;
0806   }
0807 
0808   /// Get the size of the file.
0809   /**
0810    * This function determines the size of the file, in bytes.
0811    *
0812    * @param ec Set to indicate what error occurred, if any.
0813    */
0814   uint64_t size(boost::system::error_code& ec) const
0815   {
0816     return impl_.get_service().size(impl_.get_implementation(), ec);
0817   }
0818 
0819   /// Alter the size of the file.
0820   /**
0821    * This function resizes the file to the specified size, in bytes. If the
0822    * current file size exceeds @c n then any extra data is discarded. If the
0823    * current size is less than @c n then the file is extended and filled with
0824    * zeroes.
0825    *
0826    * @param n The new size for the file.
0827    *
0828    * @throws boost::system::system_error Thrown on failure.
0829    */
0830   void resize(uint64_t n)
0831   {
0832     boost::system::error_code ec;
0833     impl_.get_service().resize(impl_.get_implementation(), n, ec);
0834     boost::asio::detail::throw_error(ec, "resize");
0835   }
0836 
0837   /// Alter the size of the file.
0838   /**
0839    * This function resizes the file to the specified size, in bytes. If the
0840    * current file size exceeds @c n then any extra data is discarded. If the
0841    * current size is less than @c n then the file is extended and filled with
0842    * zeroes.
0843    *
0844    * @param n The new size for the file.
0845    *
0846    * @param ec Set to indicate what error occurred, if any.
0847    */
0848   BOOST_ASIO_SYNC_OP_VOID resize(uint64_t n, boost::system::error_code& ec)
0849   {
0850     impl_.get_service().resize(impl_.get_implementation(), n, ec);
0851     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0852   }
0853 
0854   /// Synchronise the file to disk.
0855   /**
0856    * This function synchronises the file data and metadata to disk. Note that
0857    * the semantics of this synchronisation vary between operation systems.
0858    *
0859    * @throws boost::system::system_error Thrown on failure.
0860    */
0861   void sync_all()
0862   {
0863     boost::system::error_code ec;
0864     impl_.get_service().sync_all(impl_.get_implementation(), ec);
0865     boost::asio::detail::throw_error(ec, "sync_all");
0866   }
0867 
0868   /// Synchronise the file to disk.
0869   /**
0870    * This function synchronises the file data and metadata to disk. Note that
0871    * the semantics of this synchronisation vary between operation systems.
0872    *
0873    * @param ec Set to indicate what error occurred, if any.
0874    */
0875   BOOST_ASIO_SYNC_OP_VOID sync_all(boost::system::error_code& ec)
0876   {
0877     impl_.get_service().sync_all(impl_.get_implementation(), ec);
0878     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0879   }
0880 
0881   /// Synchronise the file data to disk.
0882   /**
0883    * This function synchronises the file data to disk. Note that the semantics
0884    * of this synchronisation vary between operation systems.
0885    *
0886    * @throws boost::system::system_error Thrown on failure.
0887    */
0888   void sync_data()
0889   {
0890     boost::system::error_code ec;
0891     impl_.get_service().sync_data(impl_.get_implementation(), ec);
0892     boost::asio::detail::throw_error(ec, "sync_data");
0893   }
0894 
0895   /// Synchronise the file data to disk.
0896   /**
0897    * This function synchronises the file data to disk. Note that the semantics
0898    * of this synchronisation vary between operation systems.
0899    *
0900    * @param ec Set to indicate what error occurred, if any.
0901    */
0902   BOOST_ASIO_SYNC_OP_VOID sync_data(boost::system::error_code& ec)
0903   {
0904     impl_.get_service().sync_data(impl_.get_implementation(), ec);
0905     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0906   }
0907 
0908 protected:
0909   /// Protected destructor to prevent deletion through this type.
0910   /**
0911    * This function destroys the file, cancelling any outstanding asynchronous
0912    * operations associated with the file as if by calling @c cancel.
0913    */
0914   ~basic_file()
0915   {
0916   }
0917 
0918 #if defined(BOOST_ASIO_HAS_IOCP)
0919   detail::io_object_impl<detail::win_iocp_file_service, Executor> impl_;
0920 #elif defined(BOOST_ASIO_HAS_IO_URING)
0921   detail::io_object_impl<detail::io_uring_file_service, Executor> impl_;
0922 #endif
0923 
0924 private:
0925   // Disallow copying and assignment.
0926   basic_file(const basic_file&) = delete;
0927   basic_file& operator=(const basic_file&) = delete;
0928 };
0929 
0930 } // namespace asio
0931 } // namespace boost
0932 
0933 #include <boost/asio/detail/pop_options.hpp>
0934 
0935 #endif // defined(BOOST_ASIO_HAS_FILE)
0936        //   || defined(GENERATING_DOCUMENTATION)
0937 
0938 #endif // BOOST_ASIO_BASIC_FILE_HPP