#include <type_traits>
#include <cstdint>
#include <cstddef>
#include <typeinfo>
#include <iostream>

template<typename T>
struct identity {
    typedef T type;
};

template<typename T, typename Head, typename... Tail>
struct best_type {
    typedef typename std::conditional<
        sizeof(Head) >= sizeof(T), 
        identity<Head>,
        best_type<T, Tail...>
    >::type::type type;
};

template<typename T>
struct type_to_integral {
    typedef typename best_type<T, uint8_t, uint16_t, uint32_t, uint64_t, uint_least64_t>::type type;
    
    static_assert(std::is_integral<type>::value, "Type is too large");
};

int main() {
    static_assert(std::is_same<type_to_integral<uint8_t>::type, uint8_t>::value, "Fail");
    static_assert(std::is_same<type_to_integral<uint16_t>::type, uint16_t>::value, "Fail");
    static_assert(std::is_same<type_to_integral<uint32_t>::type, uint32_t>::value, "Fail");
    static_assert(std::is_same<type_to_integral<uint64_t>::type, uint64_t>::value, "Fail");
}
