Hook result - Boost.Outcome documentation

# Hook result

We now tell Outcome that for every instance of our localised `result<T>`, that on failure construction only, we want custom code to be run which increments the current slot in TLS storage and writes the current stack backtrace into it.

    namespace error_code_extended
    {
      // Specialise the result construction hook for our localised result
      // We hook any non-copy, non-move, non-inplace construction, capturing a stack backtrace
      // if the result is errored.
      template <class T, class U> inline void hook_result_construction(result<T> *res, U && /*unused*/) noexcept
      {
        if(res->has_error())
        {
          // Grab the next extended info slot in the TLS
          extended_error_info &eei = mythreadlocaldata().next();

          // Write the index just grabbed into the spare uint16_t
          BOOST_OUTCOME_V2_NAMESPACE::hooks::set_spare_storage(res, mythreadlocaldata().current - 1);

          // Capture a backtrace into my claimed extended info slot in the TLS
          eei.items = ::backtrace(eei.backtrace.data(), eei.backtrace.size());
        }
      }
    }

View this code on Github

The only non-obvious part above is the call to `void set_spare_storage(basic_result|basic_outcome *, uint16_t) noexcept` .

Both `result` and `outcome` keep their internal state metadata in a `uint32_t`, half of which is not used by Outcome. As it can be very useful to keep a small unique number attached to any particular `result` or `outcome` instance, we permit user code to set those sixteen bits to anything they feel like. The corresponding function to retrieve those sixteen bits is `uint16_t spare_storage(const basic_result|basic_outcome *) noexcept` .

The state of the sixteen bits of spare storage are ignored during comparison operations.

The sixteen bits of spare storage propagate during the following operations:

1. Copy and move construction between `result`’s.
2. Copy and move construction between `outcome`’s.
3. Copy and move construction from a `result` to an `outcome`.
4. Converting copy and move constructions for all the above.
5. Assignment for all of the above.

They are NOT propagated in these operations:

1. Any conversion or translation which goes through a `failure_type` or `success_type`.
2. Any conversion or translation which goes through a `ValueOrError` concept match.
3. Any unpacking or repacking of value/error/exception e.g. a manual repack of an `outcome` into a `result`.

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