Sizing a temporary template

I have a template class that should be able to interpolate between two type instances. Therefore, my class calls a user-provided function called interpolatewith the following signature:

template<typename T>
T interpolate(uint32_t distance, const T& from, const T& to);

It distanceworks from 0to 0xFFFF.

Now I would like to provide the correct implementation for regular types T, for example, for uint32_t. Therefore, I wrote an example implementation (ignore that it is implemented only for signed types):

template<typename T>
inline auto interpolate(uint32_t distance, const T& from, const T& to)
    -> std::enable_if_t<std::is_signed<T>::value, T>
{
    return from + ((distance * (to - from)) / 0xFFFF);
}

This is great for types that are less than 32 bits in size, since the distance never exceeds 16 bits, and the result distance * (to - from)is equal uint32_t. But 32 bits are not enough to contain the result, say 0xFFFF * uint32_t- in this case, the template will need a 64-bit temporary.

Is there a standardized way so that I can choose the type "size larger" than Tto save a temporary result? Obviously, this is only necessary for internal types; user types will still need to be implemented interpolate.

+4
source share
1 answer

-, , 0 0xFFFF. , , , .. uint32_t, uint16_t. , . , :

template<typename T>
T interpolate(uint16_t factor, const T& from, const T& to);

, [from; to] - .

. , ( , 1995 !).

, , , . :

template<typename I> struct bigger_integer;
template<> struct bigger_integer<int8_t>   { typedef int16_t type; };
template<> struct bigger_integer<int16_t>  { typedef int32_t type; };
template<> struct bigger_integer<int32_t>  { typedef int64_t type; };
template<> struct bigger_integer<uint8_t>  { typedef uint16_t type; };
template<> struct bigger_integer<uint16_t> { typedef uint32_t type; };
template<> struct bigger_integer<uint32_t> { typedef uint64_t type; };

:

using I = std::make_signed_t<typename bigger_integer<T>::type>;

.

: . , , . , , , . :

template<typename T>
T interpolate(uint16_t factor, const T& from, const T& to)
{
    return T(double(from) + double(factor) * (double(to) - double(from)) / double(0xFFFF));
}

.

+1

Source: https://habr.com/ru/post/1626281/


All Articles