Upgrading the Filesystem TS
An Outcome based solution to the dual overload problem is straightforward:
namespace filesystem2
{
  // 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; }
  // Localise an outcome implementation specific to this namespace. Normally would just
  // be `result`, but for clarity we'll use `fs_result`.
  template <class T> using fs_result = outcome::result<T, failure_info>;
  /*! Copies the file at path `from` to path `to`.
  \returns Successful if file was successfully copied, otherwise the error code reported
  by the operating system plus a payload of the paths involved.
  \throws Never throws.
  */
  fs_result<void> copy_file(const path &from, const path &to) noexcept;
}
Starting at the bottom, there is now a single copy_file() function which returns a fs_result<void>.
As result is either successful or not, there is no longer any point in returning a boolean, so we
simply return void on success. On failure, as the template alias fs_result<T> above it shows,
we are returning a failure_info structure containing an error code and the same additional information
as filesystem_error provides.
It is important to note that the fact that failure_info is defined in namespace filesystem2 is very
important. This is because Outcome uses Argument Dependent Lookup (ADL)
to find the make_error_code()
function, as well as other customisation point free functions. In other words, only the namespaces as
defined by ADL are searched when finding a free function telling us what to do for failure_info,
which includes the namespace failure_info is declared into.



