Question

basically, i'd like to (at compile time) get the twice-as-wide type from a stdint type. I can do it by hand like this

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, I just want to make sure that this doesn't exist yet. I'm using visual studio 2010 C++0X (annoying, i know) and already have a boost dependency. Does anyone know of an existing implementation of this?

Was it helpful?

Solution

If you don't mind another boost dependency, then you could do this:

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

OTHER TIPS

I'd say, use Boost Integer. Demo that keeps signed-ness of the source type: 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");
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top