, - , , . :
#define CREATE_SIGNED_META_OBJ(x) template <>\
struct signed_integer_type<x> {\
typedef int##x##_t type;\
};
#define CREATE_UNSIGNED_META_OBJ(x) template <>\
struct unsigned_integer_type<x> {\
typedef uint##x##_t type;\
};
template <std::size_t length>
struct signed_integer_type;
template <std::size_t len>
struct unsigned_integer_type;
CREATE_SIGNED_META_OBJ(8)
CREATE_SIGNED_META_OBJ(16)
CREATE_SIGNED_META_OBJ(32)
CREATE_SIGNED_META_OBJ(64)
CREATE_UNSIGNED_META_OBJ(8)
CREATE_UNSIGNED_META_OBJ(16)
CREATE_UNSIGNED_META_OBJ(32)
CREATE_UNSIGNED_META_OBJ(64)
, . std::numeric_limits<Int>::min() == 0...
template <typename Int, bool>
struct get_smallest_for_max_plus_one;
template <typename Int>
struct get_smallest_for_max_plus_one<Int, true> {
typedef typename signed_integer_type<2*sizeof(Int)*8>::type type;
};
template <typename Int>
struct get_smallest_for_max_plus_one<Int, false> {
typedef typename unsigned_integer_type<sizeof(Int)*8>::type type;
};
template <typename Int>
using get_fittest_int_type = get_smallest_for_max_plus_one<Int, std::numeric_limits<Int>::min() == 0>;
get_fittest_int_type ... Coliru.
, , signed unsigned... , get_smallest_for_max_plus_one :
template <typename Int>
struct get_smallest_for_max_plus_one<Int, true> {
typedef typename unsigned_integer_type<2*sizeof(Int)*8>::type type;
};
template <typename Int>
struct get_smallest_for_max_plus_one<Int, false> {
typedef typename signed_integer_type<2*sizeof(Int)*8>::type type;
};