Tying it all together

Firstly let’s alias a more convenient form of status_result:

template <class T, class E = outcome_e::error>
using result =  //
outcome_e::status_result<T, E, outcome_e::policy::default_status_result_policy<T, E>>;
View this code on Github

(The defaulting of default_result_policy is superfluous, it’s already the default)

What follows now is very standard Outcome code. Indeed, it would compile just fine under standard Outcome with only a few typedefs.

result<file_handle, file_io_error> open_file(const char *path)  // models throws(file_io_error)
{
  file_handle ret(::fopen(path, "r"));
  if(ret)
    return ret;
  return file_io_error({errno, __LINE__, __FILE__});
}

result<void> open_resource()  // models throws(std::error)
{
  for(;;)
  {
    result<file_handle, file_io_error> r = open_file("some file");
    if(r)
      break;
    file_io_error e = r.error();
    if(e != outcome_e::errc::resource_unavailable_try_again)
    {
      // NOTE this implicitly converts from `file_io_error` to `error` via the
      // `make_status_code()` free function customisation point defined above.
      return e;
    }
  }
  // success continues here ...
  return outcome_e::success();
}

int main(void)
{
  result<void> r = open_resource();
  if(r)
    printf("Success!\n");
  else
  {
    auto e = std::move(r).error();
    // A quick demonstration that the indirection works as indicated
    printf("Returned error has a code domain of '%s', a message of '%s'\n", e.domain().name().c_str(), e.message().c_str());
    printf("\nAnd semantically comparing it to 'errc::no_such_file_or_directory' = %d\n", e == outcome_e::errc::no_such_file_or_directory);
  }
}
View this code on Github

And running this program yields:

Returned error has a code domain of 'file i/o error domain', a message of 'No such file or directory (c:\users\ned\documents\boostish\outcome\doc\src\snippets\experimental_status_code.cpp:195)'

And semantically comparing it to 'errc::no_such_file_or_directory' = 1

Conclusion

Once you get used to <system_error2> and the fact that any result with E = error is always move-only, using experimental Outcome is just like using normal Outcome. Except that codegen will be better, custom domains are safe to use in headers, semantic comparisons have guaranteed complexity bounds, and build times are much reduced.

What’s not to like? :)

Finally, if you have feedback on using experimental Outcome which you think would be of use to the standards committee when evaluating possible implementations of P0709 Zero overhead exceptions: Throwing values, please do get in touch! This especially includes successful experiences!!!