Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:33:39

0001 //
0002 // basic_file.hpp
0003 // ~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 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   explicit basic_file(const executor_type& ex,
0134       const char* path, file_base::flags open_flags)
0135     : impl_(0, ex)
0136   {
0137     boost::system::error_code ec;
0138     impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
0139     boost::asio::detail::throw_error(ec, "open");
0140   }
0141 
0142   /// Construct a basic_file without opening it.
0143   /**
0144    * This constructor initialises a file and opens it.
0145    *
0146    * @param context An execution context which provides the I/O executor that
0147    * the file will use, by default, to dispatch handlers for any asynchronous
0148    * operations performed on the file.
0149    *
0150    * @param path The path name identifying the file to be opened.
0151    *
0152    * @param open_flags A set of flags that determine how the file should be
0153    * opened.
0154    */
0155   template <typename ExecutionContext>
0156   explicit basic_file(ExecutionContext& context,
0157       const char* path, file_base::flags open_flags,
0158       constraint_t<
0159         is_convertible<ExecutionContext&, execution_context&>::value,
0160         defaulted_constraint
0161       > = defaulted_constraint())
0162     : impl_(0, 0, context)
0163   {
0164     boost::system::error_code ec;
0165     impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
0166     boost::asio::detail::throw_error(ec, "open");
0167   }
0168 
0169   /// Construct and open a basic_file.
0170   /**
0171    * This constructor initialises a file and opens it.
0172    *
0173    * @param ex The I/O executor that the file will use, by default, to
0174    * dispatch handlers for any asynchronous operations performed on the file.
0175    *
0176    * @param path The path name identifying the file to be opened.
0177    *
0178    * @param open_flags A set of flags that determine how the file should be
0179    * opened.
0180    */
0181   explicit basic_file(const executor_type& ex,
0182       const std::string& path, file_base::flags open_flags)
0183     : impl_(0, ex)
0184   {
0185     boost::system::error_code ec;
0186     impl_.get_service().open(impl_.get_implementation(),
0187         path.c_str(), open_flags, ec);
0188     boost::asio::detail::throw_error(ec, "open");
0189   }
0190 
0191   /// Construct a basic_file without opening it.
0192   /**
0193    * This constructor initialises a file and opens it.
0194    *
0195    * @param context An execution context which provides the I/O executor that
0196    * the file will use, by default, to dispatch handlers for any asynchronous
0197    * operations performed on the file.
0198    *
0199    * @param path The path name identifying the file to be opened.
0200    *
0201    * @param open_flags A set of flags that determine how the file should be
0202    * opened.
0203    */
0204   template <typename ExecutionContext>
0205   explicit basic_file(ExecutionContext& context,
0206       const std::string& path, file_base::flags open_flags,
0207       constraint_t<
0208         is_convertible<ExecutionContext&, execution_context&>::value,
0209         defaulted_constraint
0210       > = defaulted_constraint())
0211     : impl_(0, 0, context)
0212   {
0213     boost::system::error_code ec;
0214     impl_.get_service().open(impl_.get_implementation(),
0215         path.c_str(), open_flags, ec);
0216     boost::asio::detail::throw_error(ec, "open");
0217   }
0218 
0219   /// Construct a basic_file on an existing native file handle.
0220   /**
0221    * This constructor initialises a file object to hold an existing native file.
0222    *
0223    * @param ex The I/O executor that the file will use, by default, to
0224    * dispatch handlers for any asynchronous operations performed on the file.
0225    *
0226    * @param native_file A native file handle.
0227    *
0228    * @throws boost::system::system_error Thrown on failure.
0229    */
0230   basic_file(const executor_type& ex, const native_handle_type& native_file)
0231     : impl_(0, ex)
0232   {
0233     boost::system::error_code ec;
0234     impl_.get_service().assign(
0235         impl_.get_implementation(), native_file, ec);
0236     boost::asio::detail::throw_error(ec, "assign");
0237   }
0238 
0239   /// Construct a basic_file on an existing native file.
0240   /**
0241    * This constructor initialises a file object to hold an existing native file.
0242    *
0243    * @param context An execution context which provides the I/O executor that
0244    * the file will use, by default, to dispatch handlers for any asynchronous
0245    * operations performed on the file.
0246    *
0247    * @param native_file A native file.
0248    *
0249    * @throws boost::system::system_error Thrown on failure.
0250    */
0251   template <typename ExecutionContext>
0252   basic_file(ExecutionContext& context, const native_handle_type& native_file,
0253       constraint_t<
0254         is_convertible<ExecutionContext&, execution_context&>::value,
0255         defaulted_constraint
0256       > = defaulted_constraint())
0257     : impl_(0, 0, context)
0258   {
0259     boost::system::error_code ec;
0260     impl_.get_service().assign(
0261         impl_.get_implementation(), native_file, ec);
0262     boost::asio::detail::throw_error(ec, "assign");
0263   }
0264 
0265   /// Move-construct a basic_file from another.
0266   /**
0267    * This constructor moves a file from one object to another.
0268    *
0269    * @param other The other basic_file object from which the move will
0270    * occur.
0271    *
0272    * @note Following the move, the moved-from object is in the same state as if
0273    * constructed using the @c basic_file(const executor_type&) constructor.
0274    */
0275   basic_file(basic_file&& other) noexcept
0276     : impl_(std::move(other.impl_))
0277   {
0278   }
0279 
0280   /// Move-assign a basic_file from another.
0281   /**
0282    * This assignment operator moves a file from one object to another.
0283    *
0284    * @param other The other basic_file object from which the move will
0285    * occur.
0286    *
0287    * @note Following the move, the moved-from object is in the same state as if
0288    * constructed using the @c basic_file(const executor_type&) constructor.
0289    */
0290   basic_file& operator=(basic_file&& other)
0291   {
0292     impl_ = std::move(other.impl_);
0293     return *this;
0294   }
0295 
0296   // All files have access to each other's implementations.
0297   template <typename Executor1>
0298   friend class basic_file;
0299 
0300   /// Move-construct a basic_file from a file of another executor type.
0301   /**
0302    * This constructor moves a file from one object to another.
0303    *
0304    * @param other The other basic_file object from which the move will
0305    * occur.
0306    *
0307    * @note Following the move, the moved-from object is in the same state as if
0308    * constructed using the @c basic_file(const executor_type&) constructor.
0309    */
0310   template <typename Executor1>
0311   basic_file(basic_file<Executor1>&& other,
0312       constraint_t<
0313         is_convertible<Executor1, Executor>::value,
0314         defaulted_constraint
0315       > = defaulted_constraint())
0316     : impl_(std::move(other.impl_))
0317   {
0318   }
0319 
0320   /// Move-assign a basic_file from a file of another executor type.
0321   /**
0322    * This assignment operator moves a file from one object to another.
0323    *
0324    * @param other The other basic_file object from which the move will
0325    * occur.
0326    *
0327    * @note Following the move, the moved-from object is in the same state as if
0328    * constructed using the @c basic_file(const executor_type&) constructor.
0329    */
0330   template <typename Executor1>
0331   constraint_t<
0332     is_convertible<Executor1, Executor>::value,
0333     basic_file&
0334   > operator=(basic_file<Executor1>&& other)
0335   {
0336     basic_file tmp(std::move(other));
0337     impl_ = std::move(tmp.impl_);
0338     return *this;
0339   }
0340 
0341   /// Get the executor associated with the object.
0342   const executor_type& get_executor() noexcept
0343   {
0344     return impl_.get_executor();
0345   }
0346 
0347   /// Open the file using the specified path.
0348   /**
0349    * This function opens the file so that it will use the specified path.
0350    *
0351    * @param path The path name identifying the file to be opened.
0352    *
0353    * @param open_flags A set of flags that determine how the file should be
0354    * opened.
0355    *
0356    * @throws boost::system::system_error Thrown on failure.
0357    *
0358    * @par Example
0359    * @code
0360    * boost::asio::stream_file file(my_context);
0361    * file.open("/path/to/my/file", boost::asio::stream_file::read_only);
0362    * @endcode
0363    */
0364   void open(const char* path, file_base::flags open_flags)
0365   {
0366     boost::system::error_code ec;
0367     impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
0368     boost::asio::detail::throw_error(ec, "open");
0369   }
0370 
0371   /// Open the file using the specified path.
0372   /**
0373    * This function opens the file so that it will use the specified path.
0374    *
0375    * @param path The path name identifying the file to be opened.
0376    *
0377    * @param open_flags A set of flags that determine how the file should be
0378    * opened.
0379    *
0380    * @param ec Set to indicate what error occurred, if any.
0381    *
0382    * @par Example
0383    * @code
0384    * boost::asio::stream_file file(my_context);
0385    * boost::system::error_code ec;
0386    * file.open("/path/to/my/file", boost::asio::stream_file::read_only, ec);
0387    * if (ec)
0388    * {
0389    *   // An error occurred.
0390    * }
0391    * @endcode
0392    */
0393   BOOST_ASIO_SYNC_OP_VOID open(const char* path,
0394       file_base::flags open_flags, boost::system::error_code& ec)
0395   {
0396     impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
0397     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0398   }
0399 
0400   /// Open the file using the specified path.
0401   /**
0402    * This function opens the file so that it will use the specified path.
0403    *
0404    * @param path The path name identifying the file to be opened.
0405    *
0406    * @param open_flags A set of flags that determine how the file should be
0407    * opened.
0408    *
0409    * @throws boost::system::system_error Thrown on failure.
0410    *
0411    * @par Example
0412    * @code
0413    * boost::asio::stream_file file(my_context);
0414    * file.open("/path/to/my/file", boost::asio::stream_file::read_only);
0415    * @endcode
0416    */
0417   void open(const std::string& path, file_base::flags open_flags)
0418   {
0419     boost::system::error_code ec;
0420     impl_.get_service().open(impl_.get_implementation(),
0421         path.c_str(), open_flags, ec);
0422     boost::asio::detail::throw_error(ec, "open");
0423   }
0424 
0425   /// Open the file using the specified path.
0426   /**
0427    * This function opens the file so that it will use the specified path.
0428    *
0429    * @param path The path name identifying the file to be opened.
0430    *
0431    * @param open_flags A set of flags that determine how the file should be
0432    * opened.
0433    *
0434    * @param ec Set to indicate what error occurred, if any.
0435    *
0436    * @par Example
0437    * @code
0438    * boost::asio::stream_file file(my_context);
0439    * boost::system::error_code ec;
0440    * file.open("/path/to/my/file", boost::asio::stream_file::read_only, ec);
0441    * if (ec)
0442    * {
0443    *   // An error occurred.
0444    * }
0445    * @endcode
0446    */
0447   BOOST_ASIO_SYNC_OP_VOID open(const std::string& path,
0448       file_base::flags open_flags, boost::system::error_code& ec)
0449   {
0450     impl_.get_service().open(impl_.get_implementation(),
0451         path.c_str(), open_flags, ec);
0452     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0453   }
0454 
0455   /// Assign an existing native file to the file.
0456   /*
0457    * This function opens the file to hold an existing native file.
0458    *
0459    * @param native_file A native file.
0460    *
0461    * @throws boost::system::system_error Thrown on failure.
0462    */
0463   void assign(const native_handle_type& native_file)
0464   {
0465     boost::system::error_code ec;
0466     impl_.get_service().assign(
0467         impl_.get_implementation(), native_file, ec);
0468     boost::asio::detail::throw_error(ec, "assign");
0469   }
0470 
0471   /// Assign an existing native file to the file.
0472   /*
0473    * This function opens the file to hold an existing native file.
0474    *
0475    * @param native_file A native file.
0476    *
0477    * @param ec Set to indicate what error occurred, if any.
0478    */
0479   BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_file,
0480       boost::system::error_code& ec)
0481   {
0482     impl_.get_service().assign(
0483         impl_.get_implementation(), native_file, ec);
0484     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0485   }
0486 
0487   /// Determine whether the file is open.
0488   bool is_open() const
0489   {
0490     return impl_.get_service().is_open(impl_.get_implementation());
0491   }
0492 
0493   /// Close the file.
0494   /**
0495    * This function is used to close the file. Any asynchronous read or write
0496    * operations will be cancelled immediately, and will complete with the
0497    * boost::asio::error::operation_aborted error.
0498    *
0499    * @throws boost::system::system_error Thrown on failure. Note that, even if
0500    * the function indicates an error, the underlying descriptor is closed.
0501    */
0502   void close()
0503   {
0504     boost::system::error_code ec;
0505     impl_.get_service().close(impl_.get_implementation(), ec);
0506     boost::asio::detail::throw_error(ec, "close");
0507   }
0508 
0509   /// Close the file.
0510   /**
0511    * This function is used to close the file. Any asynchronous read or write
0512    * operations will be cancelled immediately, and will complete with the
0513    * boost::asio::error::operation_aborted error.
0514    *
0515    * @param ec Set to indicate what error occurred, if any. Note that, even if
0516    * the function indicates an error, the underlying descriptor is closed.
0517    *
0518    * @par Example
0519    * @code
0520    * boost::asio::stream_file file(my_context);
0521    * ...
0522    * boost::system::error_code ec;
0523    * file.close(ec);
0524    * if (ec)
0525    * {
0526    *   // An error occurred.
0527    * }
0528    * @endcode
0529    */
0530   BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
0531   {
0532     impl_.get_service().close(impl_.get_implementation(), ec);
0533     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0534   }
0535 
0536   /// Release ownership of the underlying native file.
0537   /**
0538    * This function causes all outstanding asynchronous read and write
0539    * operations to finish immediately, and the handlers for cancelled
0540    * operations will be passed the boost::asio::error::operation_aborted error.
0541    * Ownership of the native file is then transferred to the caller.
0542    *
0543    * @throws boost::system::system_error Thrown on failure.
0544    *
0545    * @note This function is unsupported on Windows versions prior to Windows
0546    * 8.1, and will fail with boost::asio::error::operation_not_supported on
0547    * these platforms.
0548    */
0549 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
0550   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
0551   __declspec(deprecated("This function always fails with "
0552         "operation_not_supported when used on Windows versions "
0553         "prior to Windows 8.1."))
0554 #endif
0555   native_handle_type release()
0556   {
0557     boost::system::error_code ec;
0558     native_handle_type s = impl_.get_service().release(
0559         impl_.get_implementation(), ec);
0560     boost::asio::detail::throw_error(ec, "release");
0561     return s;
0562   }
0563 
0564   /// Release ownership of the underlying native file.
0565   /**
0566    * This function causes all outstanding asynchronous read and write
0567    * operations to finish immediately, and the handlers for cancelled
0568    * operations will be passed the boost::asio::error::operation_aborted error.
0569    * Ownership of the native file is then transferred to the caller.
0570    *
0571    * @param ec Set to indicate what error occurred, if any.
0572    *
0573    * @note This function is unsupported on Windows versions prior to Windows
0574    * 8.1, and will fail with boost::asio::error::operation_not_supported on
0575    * these platforms.
0576    */
0577 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
0578   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
0579   __declspec(deprecated("This function always fails with "
0580         "operation_not_supported when used on Windows versions "
0581         "prior to Windows 8.1."))
0582 #endif
0583   native_handle_type release(boost::system::error_code& ec)
0584   {
0585     return impl_.get_service().release(impl_.get_implementation(), ec);
0586   }
0587 
0588   /// Get the native file representation.
0589   /**
0590    * This function may be used to obtain the underlying representation of the
0591    * file. This is intended to allow access to native file functionality
0592    * that is not otherwise provided.
0593    */
0594   native_handle_type native_handle()
0595   {
0596     return impl_.get_service().native_handle(impl_.get_implementation());
0597   }
0598 
0599   /// Cancel all asynchronous operations associated with the file.
0600   /**
0601    * This function causes all outstanding asynchronous read and write
0602    * operations to finish immediately, and the handlers for cancelled
0603    * operations will be passed the boost::asio::error::operation_aborted error.
0604    *
0605    * @throws boost::system::system_error Thrown on failure.
0606    *
0607    * @note Calls to cancel() will always fail with
0608    * boost::asio::error::operation_not_supported when run on Windows XP, Windows
0609    * Server 2003, and earlier versions of Windows, unless
0610    * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
0611    * two issues that should be considered before enabling its use:
0612    *
0613    * @li It will only cancel asynchronous operations that were initiated in the
0614    * current thread.
0615    *
0616    * @li It can appear to complete without error, but the request to cancel the
0617    * unfinished operations may be silently ignored by the operating system.
0618    * Whether it works or not seems to depend on the drivers that are installed.
0619    *
0620    * For portable cancellation, consider using the close() function to
0621    * simultaneously cancel the outstanding operations and close the file.
0622    *
0623    * When running on Windows Vista, Windows Server 2008, and later, the
0624    * CancelIoEx function is always used. This function does not have the
0625    * problems described above.
0626    */
0627 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
0628   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
0629   && !defined(BOOST_ASIO_ENABLE_CANCELIO)
0630   __declspec(deprecated("By default, this function always fails with "
0631         "operation_not_supported when used on Windows XP, Windows Server 2003, "
0632         "or earlier. Consult documentation for details."))
0633 #endif
0634   void cancel()
0635   {
0636     boost::system::error_code ec;
0637     impl_.get_service().cancel(impl_.get_implementation(), ec);
0638     boost::asio::detail::throw_error(ec, "cancel");
0639   }
0640 
0641   /// Cancel all asynchronous operations associated with the file.
0642   /**
0643    * This function causes all outstanding asynchronous read and write
0644    * operations to finish immediately, and the handlers for cancelled
0645    * operations will be passed the boost::asio::error::operation_aborted error.
0646    *
0647    * @param ec Set to indicate what error occurred, if any.
0648    *
0649    * @note Calls to cancel() will always fail with
0650    * boost::asio::error::operation_not_supported when run on Windows XP, Windows
0651    * Server 2003, and earlier versions of Windows, unless
0652    * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
0653    * two issues that should be considered before enabling its use:
0654    *
0655    * @li It will only cancel asynchronous operations that were initiated in the
0656    * current thread.
0657    *
0658    * @li It can appear to complete without error, but the request to cancel the
0659    * unfinished operations may be silently ignored by the operating system.
0660    * Whether it works or not seems to depend on the drivers that are installed.
0661    *
0662    * For portable cancellation, consider using the close() function to
0663    * simultaneously cancel the outstanding operations and close the file.
0664    *
0665    * When running on Windows Vista, Windows Server 2008, and later, the
0666    * CancelIoEx function is always used. This function does not have the
0667    * problems described above.
0668    */
0669 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
0670   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
0671   && !defined(BOOST_ASIO_ENABLE_CANCELIO)
0672   __declspec(deprecated("By default, this function always fails with "
0673         "operation_not_supported when used on Windows XP, Windows Server 2003, "
0674         "or earlier. Consult documentation for details."))
0675 #endif
0676   BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
0677   {
0678     impl_.get_service().cancel(impl_.get_implementation(), ec);
0679     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0680   }
0681 
0682   /// Get the size of the file.
0683   /**
0684    * This function determines the size of the file, in bytes.
0685    *
0686    * @throws boost::system::system_error Thrown on failure.
0687    */
0688   uint64_t size() const
0689   {
0690     boost::system::error_code ec;
0691     uint64_t s = impl_.get_service().size(impl_.get_implementation(), ec);
0692     boost::asio::detail::throw_error(ec, "size");
0693     return s;
0694   }
0695 
0696   /// Get the size of the file.
0697   /**
0698    * This function determines the size of the file, in bytes.
0699    *
0700    * @param ec Set to indicate what error occurred, if any.
0701    */
0702   uint64_t size(boost::system::error_code& ec) const
0703   {
0704     return impl_.get_service().size(impl_.get_implementation(), ec);
0705   }
0706 
0707   /// Alter the size of the file.
0708   /**
0709    * This function resizes the file to the specified size, in bytes. If the
0710    * current file size exceeds @c n then any extra data is discarded. If the
0711    * current size is less than @c n then the file is extended and filled with
0712    * zeroes.
0713    *
0714    * @param n The new size for the file.
0715    *
0716    * @throws boost::system::system_error Thrown on failure.
0717    */
0718   void resize(uint64_t n)
0719   {
0720     boost::system::error_code ec;
0721     impl_.get_service().resize(impl_.get_implementation(), n, ec);
0722     boost::asio::detail::throw_error(ec, "resize");
0723   }
0724 
0725   /// Alter the size of the file.
0726   /**
0727    * This function resizes the file to the specified size, in bytes. If the
0728    * current file size exceeds @c n then any extra data is discarded. If the
0729    * current size is less than @c n then the file is extended and filled with
0730    * zeroes.
0731    *
0732    * @param n The new size for the file.
0733    *
0734    * @param ec Set to indicate what error occurred, if any.
0735    */
0736   BOOST_ASIO_SYNC_OP_VOID resize(uint64_t n, boost::system::error_code& ec)
0737   {
0738     impl_.get_service().resize(impl_.get_implementation(), n, ec);
0739     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0740   }
0741 
0742   /// Synchronise the file to disk.
0743   /**
0744    * This function synchronises the file data and metadata to disk. Note that
0745    * the semantics of this synchronisation vary between operation systems.
0746    *
0747    * @throws boost::system::system_error Thrown on failure.
0748    */
0749   void sync_all()
0750   {
0751     boost::system::error_code ec;
0752     impl_.get_service().sync_all(impl_.get_implementation(), ec);
0753     boost::asio::detail::throw_error(ec, "sync_all");
0754   }
0755 
0756   /// Synchronise the file to disk.
0757   /**
0758    * This function synchronises the file data and metadata to disk. Note that
0759    * the semantics of this synchronisation vary between operation systems.
0760    *
0761    * @param ec Set to indicate what error occurred, if any.
0762    */
0763   BOOST_ASIO_SYNC_OP_VOID sync_all(boost::system::error_code& ec)
0764   {
0765     impl_.get_service().sync_all(impl_.get_implementation(), ec);
0766     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0767   }
0768 
0769   /// Synchronise the file data to disk.
0770   /**
0771    * This function synchronises the file data to disk. Note that the semantics
0772    * of this synchronisation vary between operation systems.
0773    *
0774    * @throws boost::system::system_error Thrown on failure.
0775    */
0776   void sync_data()
0777   {
0778     boost::system::error_code ec;
0779     impl_.get_service().sync_data(impl_.get_implementation(), ec);
0780     boost::asio::detail::throw_error(ec, "sync_data");
0781   }
0782 
0783   /// Synchronise the file data to disk.
0784   /**
0785    * This function synchronises the file data to disk. Note that the semantics
0786    * of this synchronisation vary between operation systems.
0787    *
0788    * @param ec Set to indicate what error occurred, if any.
0789    */
0790   BOOST_ASIO_SYNC_OP_VOID sync_data(boost::system::error_code& ec)
0791   {
0792     impl_.get_service().sync_data(impl_.get_implementation(), ec);
0793     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0794   }
0795 
0796 protected:
0797   /// Protected destructor to prevent deletion through this type.
0798   /**
0799    * This function destroys the file, cancelling any outstanding asynchronous
0800    * operations associated with the file as if by calling @c cancel.
0801    */
0802   ~basic_file()
0803   {
0804   }
0805 
0806 #if defined(BOOST_ASIO_HAS_IOCP)
0807   detail::io_object_impl<detail::win_iocp_file_service, Executor> impl_;
0808 #elif defined(BOOST_ASIO_HAS_IO_URING)
0809   detail::io_object_impl<detail::io_uring_file_service, Executor> impl_;
0810 #endif
0811 
0812 private:
0813   // Disallow copying and assignment.
0814   basic_file(const basic_file&) = delete;
0815   basic_file& operator=(const basic_file&) = delete;
0816 };
0817 
0818 } // namespace asio
0819 } // namespace boost
0820 
0821 #include <boost/asio/detail/pop_options.hpp>
0822 
0823 #endif // defined(BOOST_ASIO_HAS_FILE)
0824        //   || defined(GENERATING_DOCUMENTATION)
0825 
0826 #endif // BOOST_ASIO_BASIC_FILE_HPP