# 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.

For Outcome before v2.2, we must do this by inserting a specially named free function into a namespace searched by ADL:

```
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());
}
}
}
```

For Outcome v2.2 and later, we must do this by using a custom no value policy which contains
a function named `on_result_construction()`

. The function implementation is identical between
both mechanisms, just the name and placement of the function declaration differs.

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:

- Copy and move construction between
`result`

’s. - Copy and move construction between
`outcome`

’s. - Copy and move construction from a
`result`

to an`outcome`

. - Converting copy and move constructions for all the above.
- Assignment for all of the above.

They are NOT propagated in these operations:

- Any conversion or translation which goes through a
`failure_type`

or`success_type`

. - Any conversion or translation which goes through a
`ValueOrError`

concept match. - Any unpacking or repacking of value/error/exception e.g. a manual repack of an
`outcome`

into a`result`

.