The Application

The application is of course also based on Outcome, and like the HTTP library is also of mixed-failure design in that failure can be returned via error code, type erased exception_ptr or indeed a C++ exception throw.


// This is the namespace of the application which is connecting together the httplib,
// filelib and tidylib libraries into a solution.
namespace app
{
  // Create an ADL bridge so copy/move hooks will be searched for in this namespace
  struct error_code : public std::error_code
  {
    // passthrough
    using std::error_code::error_code;
    error_code() = default;
    error_code(std::error_code ec)
        : std::error_code(ec)
    {
    }
  };
  // Localise an outcome implementation for this namespace
  template <class T> using outcome = OUTCOME_V2_NAMESPACE::outcome<T, error_code /*, std::exception_ptr */>;
  using OUTCOME_V2_NAMESPACE::success;
}
View this code on Github

Here we localise a passthrough error_code solely for the purpose of ADL bridging, otherwise the localised outcome configured is the default one which comes with Outcome.

The way we are going to configure interop is as follows:

  1. The application shall use error_code for anticipated failure and C++ exception throws for unanticipated failure.
  2. We shall choose the convention that app::outcome with exception ptr solely and exclusively represents a type erased failure from a third party library.

Thus if one calls .value() on an app::outcome, both anticipated failure within the app and type erased failure from a third party library shall be converted to a C++ exception throw.