I wanted to write some template functions to handle type punning in a defined way, so I came up with these two functions. The first takes an object and converts it with punning to another. It ensures that both types are POD and of equal size. The second was intended to simply take any pointer (as if void*) but still check to make sure that the pointer was to a POD type. The problem I ran into is if I pass a non-const pointer then the first function will get used instead. What would be the best way of handling this?
template <class TO, class FROM>
FORCE_INLINE TO punning_cast(const FROM &input)
{
static_assert(std::is_pod<TO>::value, "TO must be POD");
static_assert(std::is_pod<FROM>::value, "FROM must be POD");
static_assert(sizeof(TO) == sizeof(FROM), "TO and FROM must be the same size");
TO out;
std::memcpy(&out, &input, sizeof(TO));
return out;
}
template <class TO, class FROM>
FORCE_INLINE TO punning_cast(const FROM *input)
{
static_assert(std::is_pod<TO>::value, "TO must be POD");
static_assert(std::is_pod<FROM>::value, "FROM must be POD");
TO out;
std::memcpy(&out, input, sizeof(TO));
return out;
}