template<typename type> struct type_traits; template<> struct type_traits <unsigned char> { typedef unsigned char current_type; typedef unsigned short next_type; }; template<> struct type_traits <unsigned short> { typedef unsigned short current_type; typedef unsigned int next_type; }; template<> struct type_traits <unsigned int> { typedef unsigned int current_type; typedef unsigned long next_type; }; template<> struct type_traits <unsigned long> { typedef unsigned long current_type; typedef unsigned long long next_type; }; template<> struct type_traits <unsigned long long int> { typedef unsigned long long int current_type; }; template<> struct type_traits <signed char> { typedef signed char current_type; typedef short next_type; }; template<> struct type_traits <short> { typedef short current_type; typedef int next_type; }; template<> struct type_traits <int> { typedef int current_type; typedef long next_type; }; template<> struct type_traits <long> { typedef long current_type; typedef long long next_type; }; template<> struct type_traits <long long int> { typedef long long int current_type;};
// template<typename type, bool> struct type_choice { typedef typename type_traits<type>::current_type std_type; }; template<typename type> struct type_choice<type, false> { typedef typename type_traits<type>::next_type next_type; typedef typename type_choice<next_type, sizeof(next_type) == capacity>::std_type std_type; };
// template <bool is_signed> struct base_type_selector { typedef signed char base_type; }; template <> struct base_type_selector<false> { typedef unsigned char base_type; };
typedef typename type_choice< typename base_type_selector<is_signed>::base_type, sizeof(base_type_selector<is_signed>::base_type) == capacity >::std_type type;
template <size_t capacity, bool is_signed> class fixed_int { // template <int x> struct unsupported_capacity { int i[1/(xx)]; }; template <> struct unsupported_capacity<1> {}; template <> struct unsupported_capacity<2> {}; template <> struct unsupported_capacity<4> {}; template <> struct unsupported_capacity<8> {}; // , template<typename type> struct type_traits; template<> struct type_traits <unsigned char> { typedef unsigned char current_type; typedef unsigned short next_type; }; template<> struct type_traits <unsigned short> { typedef unsigned short current_type; typedef unsigned int next_type; }; template<> struct type_traits <unsigned int> { typedef unsigned int current_type; typedef unsigned long next_type; }; template<> struct type_traits <unsigned long> { typedef unsigned long current_type; typedef unsigned long long next_type; }; template<> struct type_traits <unsigned long long int> { typedef unsigned long long int current_type; typedef unsupported_capacity<capacity> next_type; }; template<> struct type_traits <signed char> { typedef signed char current_type; typedef short next_type; }; template<> struct type_traits <short> { typedef short current_type; typedef int next_type; }; template<> struct type_traits <int> { typedef int current_type; typedef long next_type; }; template<> struct type_traits <long> { typedef long current_type; typedef long long next_type; }; template<> struct type_traits <long long int> { typedef long long int current_type; typedef unsupported_capacity<capacity> next_type;}; // template<typename type, bool> struct type_choice { typedef typename type_traits<type>::current_type std_type; }; template<typename type> struct type_choice<type, false> { typedef typename type_traits<type>::next_type next_type; typedef typename type_choice<next_type, sizeof(next_type) == capacity>::std_type std_type; }; // template <bool is_signed> struct base_type_selector { typedef signed char base_type; }; template <> struct base_type_selector<false> { typedef unsigned char base_type; }; public: typedef typename type_choice< typename base_type_selector<is_signed>::base_type, sizeof(base_type_selector<is_signed>::base_type) == capacity >::std_type type; };
typedef fixed_int<1, false>::type uint8; typedef fixed_int<2, false>::type uint16; typedef fixed_int<4, false>::type uint32; typedef fixed_int<8, false>::type uint64; typedef fixed_int<1, true>::type int8; typedef fixed_int<2, true>::type int16; typedef fixed_int<4, true>::type int32; typedef fixed_int<8, true>::type int64;
... int32 x1; uint64 x2; fixed_int<2, true>::type x3; std::wcout<<typeid(x1).name()<<std::endl; std::wcout<<typeid(x2).name()<<std::endl; std::wcout<<typeid(x3).name()<<std::endl; ...
int unsigned __int64 short
// template <int x> struct unsupported_capacity { int i[1/(xx)]; }; template <> struct unsupported_capacity<1> {}; template <> struct unsupported_capacity<2> {}; template <> struct unsupported_capacity<4> {}; template <> struct unsupported_capacity<8> {};
exp4.cpp(127): error C2057: expected constant expression exp4.cpp(156) : see reference to class template instantiation 'fixed_int<3,true>::unsupported_capacity<3>' being compiled ...
Source: https://habr.com/ru/post/280542/