#include <iostream>
template <typename T> struct next_t {};
template <> struct next_t<unsigned long long> { typedef unsigned long type; };
template <> struct next_t<unsigned long> { typedef unsigned int type; };
template <> struct next_t<unsigned int> { typedef unsigned short type; };
template <> struct next_t<unsigned short> { typedef unsigned char type; };
template <typename Max_t, Max_t upto_n, typename Best_t=Max_t, typename Try_t=unsigned long long, bool try_is_better = (sizeof(Try_t) <= sizeof(Best_t) && upto_n == Max_t(Try_t(upto_n)))>
struct tight_int {
typedef typename tight_int<Max_t, upto_n, Best_t, typename next_t<Try_t>::type>::type type;
};
template <typename Max_t, Max_t upto_n, typename Best_t, typename Try_t>
struct tight_int<Max_t, upto_n, Best_t, Try_t, true> {
typedef typename tight_int<Max_t, upto_n, Try_t, typename next_t<Try_t>::type>::type type;
};
template <typename Max_t, Max_t upto_n, typename Best_t>
struct tight_int<Max_t, upto_n, Best_t, unsigned char, true> {
typedef unsigned char type;
};
template <typename Max_t, Max_t upto_n, typename Best_t>
struct tight_int<Max_t, upto_n, Best_t, unsigned char, false> {
typedef Best_t type;
};
int main() {
typedef tight_int<size_t, 255>::type tight_255_t;
typedef tight_int<size_t, 256>::type tight_256_t;
typedef tight_int<size_t, 65535>::type tight_65535_t;
typedef tight_int<size_t, 65536>::type tight_65536_t;
std::cout << "255 : " << sizeof(tight_255_t) << std::endl;
std::cout << "256 : " << sizeof(tight_256_t) << std::endl;
std::cout << "65535 : " << sizeof(tight_65535_t) << std::endl;
std::cout << "65536 : " << sizeof(tight_65536_t) << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHN0cnVjdCBuZXh0X3Qge307CnRlbXBsYXRlIDw+IHN0cnVjdCBuZXh0X3Q8dW5zaWduZWQgbG9uZyBsb25nPiB7IHR5cGVkZWYgdW5zaWduZWQgbG9uZyB0eXBlOyB9Owp0ZW1wbGF0ZSA8PiBzdHJ1Y3QgbmV4dF90PHVuc2lnbmVkIGxvbmc+ICAgICAgeyB0eXBlZGVmIHVuc2lnbmVkIGludCB0eXBlOyB9Owp0ZW1wbGF0ZSA8PiBzdHJ1Y3QgbmV4dF90PHVuc2lnbmVkIGludD4gICAgICAgeyB0eXBlZGVmIHVuc2lnbmVkIHNob3J0IHR5cGU7IH07CnRlbXBsYXRlIDw+IHN0cnVjdCBuZXh0X3Q8dW5zaWduZWQgc2hvcnQ+ICAgICB7IHR5cGVkZWYgdW5zaWduZWQgY2hhciB0eXBlOyB9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIE1heF90LCBNYXhfdCB1cHRvX24sIHR5cGVuYW1lIEJlc3RfdD1NYXhfdCwgdHlwZW5hbWUgVHJ5X3Q9dW5zaWduZWQgbG9uZyBsb25nLCBib29sIHRyeV9pc19iZXR0ZXIgPSAoc2l6ZW9mKFRyeV90KSA8PSBzaXplb2YoQmVzdF90KSAmJiB1cHRvX24gPT0gTWF4X3QoVHJ5X3QodXB0b19uKSkpPgpzdHJ1Y3QgdGlnaHRfaW50IHsKICAgIHR5cGVkZWYgdHlwZW5hbWUgdGlnaHRfaW50PE1heF90LCB1cHRvX24sIEJlc3RfdCwgdHlwZW5hbWUgbmV4dF90PFRyeV90Pjo6dHlwZT46OnR5cGUgdHlwZTsgCn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgTWF4X3QsIE1heF90IHVwdG9fbiwgdHlwZW5hbWUgQmVzdF90LCB0eXBlbmFtZSBUcnlfdD4Kc3RydWN0IHRpZ2h0X2ludDxNYXhfdCwgdXB0b19uLCBCZXN0X3QsIFRyeV90LCB0cnVlPiAgewogICAgdHlwZWRlZiB0eXBlbmFtZSB0aWdodF9pbnQ8TWF4X3QsIHVwdG9fbiwgVHJ5X3QsIHR5cGVuYW1lIG5leHRfdDxUcnlfdD46OnR5cGU+Ojp0eXBlIHR5cGU7IAp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIE1heF90LCBNYXhfdCB1cHRvX24sIHR5cGVuYW1lIEJlc3RfdD4Kc3RydWN0IHRpZ2h0X2ludDxNYXhfdCwgdXB0b19uLCBCZXN0X3QsIHVuc2lnbmVkIGNoYXIsIHRydWU+ICB7CiAgICB0eXBlZGVmIHVuc2lnbmVkIGNoYXIgdHlwZTsgCn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgTWF4X3QsIE1heF90IHVwdG9fbiwgdHlwZW5hbWUgQmVzdF90PgpzdHJ1Y3QgdGlnaHRfaW50PE1heF90LCB1cHRvX24sIEJlc3RfdCwgdW5zaWduZWQgY2hhciwgZmFsc2U+IHsKICAgIHR5cGVkZWYgQmVzdF90IHR5cGU7IAp9OwoKaW50IG1haW4oKSB7CiAgICB0eXBlZGVmIHRpZ2h0X2ludDxzaXplX3QsIDI1NT46OnR5cGUgdGlnaHRfMjU1X3Q7CiAgICB0eXBlZGVmIHRpZ2h0X2ludDxzaXplX3QsIDI1Nj46OnR5cGUgdGlnaHRfMjU2X3Q7CiAgICB0eXBlZGVmIHRpZ2h0X2ludDxzaXplX3QsIDY1NTM1Pjo6dHlwZSB0aWdodF82NTUzNV90OwogICAgdHlwZWRlZiB0aWdodF9pbnQ8c2l6ZV90LCA2NTUzNj46OnR5cGUgdGlnaHRfNjU1MzZfdDsKICAgIHN0ZDo6Y291dCA8PCAiMjU1ICAgOiAiIDw8IHNpemVvZih0aWdodF8yNTVfdCkgPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0IDw8ICIyNTYgICA6ICIgPDwgc2l6ZW9mKHRpZ2h0XzI1Nl90KSA8PCBzdGQ6OmVuZGw7CiAgICBzdGQ6OmNvdXQgPDwgIjY1NTM1IDogIiA8PCBzaXplb2YodGlnaHRfNjU1MzVfdCkgPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0IDw8ICI2NTUzNiA6ICIgPDwgc2l6ZW9mKHRpZ2h0XzY1NTM2X3QpIDw8IHN0ZDo6ZW5kbDsKfQ==