Inspecting outcome<T, EC, EP> - Boost.Outcome documentation

# Inspecting outcome

Continuing with the previous example, in `Layer3` we have function `z` which again reports failures via exceptions. It will call function `h` from `Layer2_old` which returns `outcome<int>` (which may store a `double` or an `std::error_code` or an `std::exception_ptr`). The goal is to unpack it to either the successful return value `int` or to throw an appropriate exception: if we are storing an `std::exception_ptr` just rethrow it. If we are storing an `std::error_code` throw it as `std::system_error`, which is designed to store `std::error_code`’s:

    auto z() -> int // throws on failure
    {
      if (outcome::outcome<int> o = old::h())
        return o.value();
      else if (o.has_exception())
        std::rethrow_exception(o.exception());
      else
        throw std::system_error{o.error()};
    }

View this code on Github

Function `has_exception` checks if it is `EP` (`std::exception_ptr`) that is stored, function `exception` accesses it. Similarly, function `error` accesses the `EC` (`std::error_code`) if it is stored. `outcome<>` also has a function `has_failure` to check if either `EC` or `EP` is being stored.

It would seem obvious that the above pattern of “unpacking” `outcome<>` is so common that it ought to be implemented inside function `.value()`, so function `z` could be written as:

    return old::h().value();

And this is exactly what the aforementioned no-value policy template argument is for, which is described in the next section.

Last revised: February 08, 2019 at 22:18:08 UTC