The File I/O library

The File I/O library we shall be using is very similar to the one we saw earlier in this tutorial:


// You may remember this from the tutorial section on Custom Payloads
namespace filelib
{
  // Error code + paths related to a failure. Also causes ADL discovery to check this namespace.
  struct failure_info
  {
    std::error_code ec;
    path path1{}, path2{};
  };

  // Tell Outcome that failure_info is to be treated as a std::error_code
  inline const std::error_code &make_error_code(const failure_info &fi) { return fi.ec; }

  // Tell Outcome that no-value observation should throw a custom exception
  inline void throw_as_system_error_with_payload(failure_info fi)
  {
    // If the error code is not filesystem related e.g. ENOMEM, throw that as a standard STL exception.
    OUTCOME_V2_NAMESPACE::try_throw_std_exception_from_error(fi.ec);
    // Throw the exact same filesystem_error exception which the throwing copy_file() edition does.
    throw filesystem_error(fi.ec.message(), std::move(fi.path1), std::move(fi.path2), fi.ec);
  }

  // Localise a result implementation specific to this namespace.
  template <class T> using result = OUTCOME_V2_NAMESPACE::result<T, failure_info>;

  // Writes a chunk of data to some file. Returns bytes written, or failure_info. Never throws exceptions.
  result<size_t> write_file(string_view chunk) noexcept;
}
View this code on Github

This uses the advanced Outcome feature of programming the lazy synthesis of custom C++ exception throws from a payload carrying E type called failure_info. Like the HTTP library, it too template aliases a localised result implementation into its namespace with ADL bridging so Outcome customisation points can be discovered.