в основном, я хотел бы (во время компиляции) получить тип с двойной шириной от типа stdint. Я могу сделать это вручную, как это
template <typename T>
class twice_as_wide{};
template<>
class twice_as_wide<uint8_t>
{
public:
typedef uint16_t type;
};
template<>
class twice_as_wide<int8_t>
{
public:
typedef int16_t type;
};
template<>
class twice_as_wide<uint16_t>
{
public:
typedef uint32_t type;
};
Я просто хочу убедиться, что этого еще не существует. Я использую Visual Studio 2010 C ++ 0X (раздражает, я знаю), и у меня уже есть буст-зависимость. Кто-нибудь знает о существующей реализации этого?
Если вы не возражаете против другой буст-зависимости, то вы можете сделать это:
#include <type_traits>
#include <boost/integer.hpp>template <typename T, bool is_unsigned = std::is_unsigned<T>::value>
struct twice_as_wide
{
typedef typename boost::uint_t< 2 * std::numeric_limits<T>::digits>::exact type;
};
template<typename T>
struct twice_as_wide<T, false>
{
typedef typename boost::int_t< 2 * (std::numeric_limits<T>::digits + 1)>::exact type;
};
template< typename T>
using twice_as_wide_t = typename twice_as_wide<T>::type;
Я бы сказал, используйте Boost Integer. Демо, которое держит signed
-ность типа источника: Жить на Колиру
#include <boost/integer.hpp>
#include <limits>
namespace helpers
{
// wrappers around Boost Integer http://www.boost.org/doc/libs/1_54_0/libs/integer/doc/html/boost_integer/integer.html#boost_integer.integer.sized
template <bool is_signed, int bin_digits> struct select_twice;
template <int bin_digits> struct select_twice<true, bin_digits> {
using type = typename boost::int_t<bin_digits + 1>::least;
};
template <int bin_digits> struct select_twice<false, bin_digits> {
using type = typename boost::uint_t<bin_digits>::least;
};
}
template <typename Int>
using select_twice = helpers::select_twice<std::numeric_limits<Int>::is_signed, std::numeric_limits<Int>::digits*2>;
template <typename Int>
using twice_t = typename select_twice<Int>::type;
int main()
{
static_assert(std::is_same<uint16_t, twice_t<uint8_t>>::value, "oops");
static_assert(std::is_same<uint32_t, twice_t<uint16_t>>::value, "oops");
static_assert(std::is_same<uint64_t, twice_t<uint32_t>>::value, "oops");
}