Example C++ function

Let us start with a simple C++ function which we wish to make available to C code:

namespace outcome_e = OUTCOME_V2_NAMESPACE::experimental;

// Fill the supplied buffer with the integer v converted to a string,
// returning length of string minus null terminator
outcome_e::status_result<size_t> to_string(char *buffer, size_t bufferlen, int v) noexcept
{
  try
  {
    // Could throw an exception!
    std::string temp(std::to_string(v));

    // Will this string exceed the supplied buffer?
    if(temp.size() + 1 > bufferlen)
      return outcome_e::errc::no_buffer_space;

    // Copy the string into the supplied buffer, and return length of string
    memcpy(buffer, temp.data(), temp.size() + 1);
    return temp.size();
  }
  catch(...)
  {
    // This is the <system_error2> analogue of Standard Outcome's
    // error_from_exception() utility function. It consumes an exception
    // ptr (defaulted to current exception), and tries to match it to a
    // standard C++ library exception type, returning a system_code
    // with an appropriate code domain (generic_code, posix_code,
    // win32_code).
    //
    // Note that using this function requires including
    // <outcome/experimental/status-code/include/system_code_from_exception.hpp>
    // It is NOT included by Experimental Outcome by default.
    return outcome_e::system_code_from_exception();
  }
}
View this code on Github

As the alias status_result<size_t> defaults the erased type to the alias system_code, the to_string() function returns (in concrete types) basic_result<size_t, status_code<erased<intptr_t>>>.

The standard Outcome function referenced is documented at std::error_code error_from_exception(std::exception_ptr &&ep = std::current_exception(), std::error_code not_matched = std::make_error_code(std::errc::resource_unavailable_try_again)) noexcept . The proposed <system_error2> reference library implementation provides an identically named function taking similar parameters, but it returns a outcome_e::system_code (status_code<erased<intptr_t>>) instead of a std::error_code.