2013-09-18 4 views
2

В основном, я бы хотел (во время компиляции) получить тип в два раза по типу 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; 
}; 

ect, я просто хочу убедиться, что этого еще нет. Я использую Visual Studio 2010 C++ 0X (раздражает, я знаю) и уже имеет зависимость от boost. Кто-нибудь знает о существующей реализации этого?

ответ

1

Если вы не против еще повысить зависимость, то вы можете сделать это:

#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; 
+0

Просто быть педантичным, вы должны использовать 'STD :: numeric_limits :: digits' вместо' 8 * SizeOf (T) '. В большинстве систем есть 8 бит в байте, но это неверно для всех систем. –

+0

@MarkLakata: вы правы, исправляя это в моем anser. – dhavenith

0

Я бы сказал, использование Повысьте Integer. Демонстрация, которая держит signed -ness типа источника: Live on Coliru

#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"); 
} 
Смежные вопросы