#include <iostream>

struct Null { };

template<typename H, typename T>
struct TypeList
{
	typedef H Head;
	typedef T Tail;
};


template<typename T, unsigned S, bool C=(sizeof(typename T::Head)==S/8)>
struct IntChooser;

template<typename T, unsigned S>
struct IntChooser<T, S, true>
{
	typedef typename T::Head Type;
};

template<typename T, unsigned S>
struct IntChooser<T, S, false>
{
	typedef typename IntChooser<typename T::Tail, S>::Type Type;
};


typedef TypeList<char, TypeList<short, TypeList<int, TypeList<long, TypeList<long long, Null> > > > >
	IntTypes;


template<unsigned S>
struct Int
{
	typedef typename IntChooser<IntTypes, S>::Type Type;
};


typedef Int<8>::Type Int8;
typedef Int<16>::Type Int16;
typedef Int<32>::Type Int32;
typedef Int<64>::Type Int64;


using namespace std;

int main()
{
	cout<<"sizeof(Int8) == "<<sizeof(Int8)<<'\n';
	cout<<"sizeof(Int16) == "<<sizeof(Int16)<<'\n';
	cout<<"sizeof(Int32) == "<<sizeof(Int32)<<'\n';
	cout<<"sizeof(Int64) == "<<sizeof(Int64)<<'\n';
	return 0;
}
