Attempt times:
template<typename THigh, typename TLow> inline size_t compact(THigh hi, TLow lo){ return (reinterpret_cast<size_t>(hi)<<32) | reinterpret_cast<size_t>(lo); }
Types THigh
, TLow
can be a numeric type, or a pointer type in any combination. The compiler swears invalid cast
on the proposed version.
Attempt two:
template<typename THigh, typename TLow> inline size_t compact(THigh hi, TLow lo){ return (static_cast<size_t>(hi)<<32) | static_cast<size_t>(lo); }
The compiler again swears invalid static_cast
. Alteration in the macro gives absolutely nothing. You can write four functions, but their code is essentially identical.
You can use outdated c-style:
template<typename THigh, typename TLow> inline size_t compact(THigh hi, TLow lo){ return ((size_t)(hi)<<32) | (size_t)(lo); }
But this style hides (subtle) type casting.
In general, you need to combine all the options:
void*, size_t
size_t, void*
void*, void*
This feature is needed to convert data from MMIO with 32-bit access to 64-bit system pointers. That is, the major or minor part is a number, and the rest is a pointer. The number and the number will only be a side effect.
size_t
is 64 bits wide. Pointers are 64 bits. All - 64 bits, only one parameters - numbers, and other pointers.