An invoker's erased function pointer was typed R (*)(proxy<F>&, D,
Args...), so its type named the facade it was built for. That is fine
while metadata is only ever read by a proxy of exactly that facade, but
it prevents one proxy from reusing another's invoker: two proxy types
have different layouts, so passing one where the other is expected is
not valid.
Introduce erased_context, which carries only a pointer to the storage of
the contained value, and type invokers as invoker<Ctx, O>. Invocation
now resolves the contained type inside the context rather than through
reinterpret_invoke, and the lifetime dispatches take a void* rather than
a target proxy, so their invokers no longer mention F either. Resetting
the source metadata after an rvalue-qualified call moves to the call
site, where the facade is known.
Declare ptr_ ahead of meta_ so that the storage of the contained value
lies at offset 0. Every invocation now builds a context from it, and at
offset 0 that context is the address of the proxy itself. Where a proxy
is invoked more than once, the caller then keeps a single value live
instead of a separate context pointer: on aarch64 that removes a spill
and reload of the context across the first call, and shrinks the frame
by 16 bytes. Neither sizeof(proxy) nor its alignment changes.
relocate_dispatch becomes a tag with its own erased_context
specialization, which absorbs the bitwise-relocation path that used to
be selected via internal_dispatch, and internal_dispatch is removed.
substitution_dispatch needs the same path, because it relocates a
bitwise-relocatable value without requiring it to be move-constructible,
so it gets a specialization too; both it and the specialization drop out
once `super` replaces substitution.
Removes the public reinterpret_invoke, which had no remaining use: the
invoker macro was its only caller inside the library.
An invoker's erased function pointer was typed R (*)(proxy<F>&, D, Args...), so its type named the facade it was built for. That is fine while metadata is only ever read by a proxy of exactly that facade, but it prevents one proxy from reusing another's invoker: two proxy types have different layouts, so passing one where the other is expected is not valid. Reusing a base facade's invokers is what super (more PRs coming ahead) needs.
Declaring ptr_ first is what keeps the new indirection free at the call site. Where a proxy is invoked more than once, the caller keeps a single value live instead of a separate context pointer. On aarch64 that removes a spill and reload of the context across the first call and shrinks the frame by 16 bytes:
substitution_dispatch needs the same relocation path, because it relocates a bitwise-relocatable value without requiring it to be move-constructible, so it gets a specialization too. That specialization will be removed together with substitution_dispatch in the last PR of this stack.
Breaking change. Removes the public reinterpret_invoke.