С++ целочисленный тип в два раза больше ширины заданного типа

В этом примере coord_squared_t является псевдонимом для целочисленного типа с по меньшей мере вдвое большим размером целочисленного типа coord_t:

typedef int_least32_t coord_t;

coord_squared_t CalculateSquaredHypothenuse(coord_t x, coord_t y){
    coord_squared_t _x=x;
    coord_squared_t _y=y;
    return _x*_x+_y*_y;
}

Что можно использовать для выражения coord_squared_t в терминах coord_t? Есть ли что-нибудь в стандартной библиотеке, которая позволяет мне делать что-то вроде double_width<coord_t>::type, чтобы получить правильную ширину, вместо явного выбора типа?

С++ 11 или С++ 14 в порядке.

Ответы

Ответ 1

Вы можете использовать boost::int_t:

using coord_squared_t = boost::int_t<sizeof(coord_t)*CHAR_BIT*2>::least;

Ответ 2

Если вы не хотите использовать Boost, вы можете просто реализовать это вручную с помощью некоторых специализаций:

template <class > struct next_size;
template <class T> using next_size_t = typename next_size<T>::type;
template <class T> struct tag { using type = T; };

template <> struct next_size<int_least8_t>  : tag<int_least16_t> { };
template <> struct next_size<int_least16_t> : tag<int_least32_t> { };
template <> struct next_size<int_least32_t> : tag<int_least64_t> { };
template <> struct next_size<int_least64_t> : tag<???> { };

// + others if you want the other int types

И затем:

using coord_squared_t = next_size_t<coord_t>;

В качестве альтернативы вы можете специализироваться на основе количества бит:

template <size_t N> struct by_size : by_size<N+1> { };
template <size_t N> using by_size_t = typename by_size<N>::type;
template <class T> struct tag { using type = T; };

template <> struct by_size<8>  : tag<int_least8_t> { };
template <> struct by_size<16> : tag<int_least16_t> { };
template <> struct by_size<32> : tag<int_least32_t> { };
template <> struct by_size<64> : tag<int_least64_t> { };

Таким образом, что-то вроде by_size<45>::type является int_least64_t из-за наследования. И тогда это будет похоже на ответ Boost:

using coord_squared_t = by_size_t<2 * CHAR_BIT * sizeof(coord_t)>;