/* fully c++03 conform (apart from long long, but which is supported by
major compilers). */
#include <cstdio>
/* chooses type A if cond == true, chooses type B if cond == false */
template <bool cond, typename A, typename B>
struct Condition {
typedef A type;
};
template <typename A, typename B>
struct Condition<false, A, B> {
typedef B type;
};
/* create macros for static if. IFD is used if the
condition depends on template parameters. IF/D cannot
be nested, since the nested macro call would contain
commas. A solution is '...', which is available in next
c++. */
#define IF( X, A, B) Condition<(X), A, B>::type
#define IFD(X, A, B) typename IF((X), A, B)
template <int nbits>
struct Integer {
/* define the nested Condition types step by step. */
typedef IFD(nbits <= 64, long long, long long) d3;
typedef IFD(nbits <= 32, long, d3) d2;
typedef IFD(nbits <= 16, short, d2) d1;
/* result type */
typedef IFD(nbits <= 8, signed char, d1) type;
/* if nbits > 64, cause a compile time error */
struct Empty {};
struct NBitsGreater64;
IFD(nbits <= 64, Empty, NBitsGreater64) checker;
};
int main() {
Integer< 8 >::type i ;
Integer< 16 >::type j ;
Integer< 29 >::type k ;
Integer< 68 >::type l ;
std::printf("%d %d %d %d\n",
sizeof(i), sizeof(j), sizeof(k), sizeof(l));
return 0;
}