Introduce an interface for target_impl that supports default implementations
Design goals:
- No runtime indirection
- Permit header-only implementations for inlining under nvcc
- Permit default implementations
- Catch various errors at compile time
- Syntactically reasonable
- Familiar to C++ developers
The API is an adaption of the curiously recuring template pattern, modified to
use static calls throughout. This gives the impl::Bits::pack syntax that matches
free functions in a namespace, which is essentially what the static functions in
a non-template class are.
Marking methods as = delete provides better diagnostics than missing symbols
at link time. The friend/private annotations are analogous to the non-virtual
interface of runtime dispatch.
It is odd to provide a default for pack but not for unpack, when would this ever be useful?
It also seems overly complicated to redirect here in the first place. Subclasses could as well provide pack/unpack directly, couldn't thy?