#include <tr1/type_traits>
#include <type_traits>
namespace detail {
using namespace std::tr1;
template <typename T> struct promote { typedef T type; };
template <> struct promote<bool> { typedef int type; };
template <> struct promote<char> { typedef int type; };
template <> struct promote<signed char> { typedef int type; };
template <> struct promote<unsigned char> { typedef int type; };
template <> struct promote<short> { typedef int type; };
template <> struct promote<unsigned short> { typedef int type; };
template <typename> struct rank;
template <> struct rank<int> { enum { value = 0 }; };
template <> struct rank<unsigned> { enum { value = 0 }; };
template <> struct rank<long> { enum { value = 1 }; };
template <> struct rank<unsigned long> { enum { value = 1 }; };
template <> struct rank<long long> { enum { value = 2 }; };
template <> struct rank<unsigned long long> { enum { value = 2 }; };
template <> struct rank<float> { enum { value = 3 }; };
template <> struct rank<double> { enum { value = 4 }; };
template <> struct rank<long double> { enum { value = 5 }; };
template <typename> struct make_unsigned;
template <> struct make_unsigned<int> { typedef unsigned type; };
template <> struct make_unsigned<long> { typedef unsigned long type; };
template <> struct make_unsigned<long long> { typedef unsigned long long type; };
template < typename A
, typename B
, bool Is_fp_or_same_signs_or_A_is_unsigned_or_bigger >
struct common_type_impl {
typedef A type;
};
template <typename A, typename B>
struct common_type_impl<A, B, false>
: make_unsigned<A> {};
template <typename A, typename B, bool A_is_higher>
struct common_type_swap
: common_type_impl< A
, B
, is_floating_point<A>::value || is_floating_point<B>::value
|| (is_signed<A>::value == is_signed<B>::value)
|| is_unsigned<A>::value || (sizeof(A) > sizeof(B))
> {};
template <typename A, typename B>
struct common_type_swap<A, B, false>
: common_type_swap<B, A, true> {};
template <typename A, typename B>
struct common_type
: common_type_swap<A, B, (rank<A>::value > rank<B>::value)> {};
}
template <typename A, typename B>
struct common_type
: detail::common_type< typename detail::promote<A>::type
, typename detail::promote<B>::type > {};
template <typename A, typename B>
void test() {
using common_type = typename common_type<A, B>::type;
using sum_type = decltype(A{} + B{});
static_assert(std::is_same<common_type, sum_type>{}, "");
};
template <typename T>
void test2() {
test<T, bool>();
test<T, char>();
test<T, signed char>();
test<T, unsigned char>();
test<T, short>();
test<T, unsigned short>();
test<T, int>();
test<T, unsigned>();
test<T, long>();
test<T, unsigned long>();
test<T, long long>();
test<T, unsigned long long>();
test<T, float>();
test<T, double>();
test<T, long double>();
};
int main() {
test2<bool>();
test2<char>();
test2<signed char>();
test2<unsigned char>();
test2<short>();
test2<unsigned short>();
test2<int>();
test2<unsigned>();
test2<long>();
test2<unsigned long>();
test2<long long>();
test2<unsigned long long>();
test2<float>();
test2<double>();
test2<long double>();
}
I2luY2x1ZGUgPHRyMS90eXBlX3RyYWl0cz4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKbmFtZXNwYWNlIGRldGFpbCB7CiAgICB1c2luZyBuYW1lc3BhY2Ugc3RkOjp0cjE7CgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHN0cnVjdCBwcm9tb3RlIHsgdHlwZWRlZiBUIHR5cGU7IH07CiAgICB0ZW1wbGF0ZSA8PiBzdHJ1Y3QgcHJvbW90ZTxib29sPiB7IHR5cGVkZWYgaW50IHR5cGU7IH07CiAgICB0ZW1wbGF0ZSA8PiBzdHJ1Y3QgcHJvbW90ZTxjaGFyPiB7IHR5cGVkZWYgaW50IHR5cGU7IH07CiAgICB0ZW1wbGF0ZSA8PiBzdHJ1Y3QgcHJvbW90ZTxzaWduZWQgY2hhcj4geyB0eXBlZGVmIGludCB0eXBlOyB9OwogICAgdGVtcGxhdGUgPD4gc3RydWN0IHByb21vdGU8dW5zaWduZWQgY2hhcj4geyB0eXBlZGVmIGludCB0eXBlOyB9OwogICAgdGVtcGxhdGUgPD4gc3RydWN0IHByb21vdGU8c2hvcnQ+IHsgdHlwZWRlZiBpbnQgdHlwZTsgfTsKICAgIHRlbXBsYXRlIDw+IHN0cnVjdCBwcm9tb3RlPHVuc2lnbmVkIHNob3J0PiB7IHR5cGVkZWYgaW50IHR5cGU7IH07CgogICAgdGVtcGxhdGUgPHR5cGVuYW1lPiBzdHJ1Y3QgcmFuazsKICAgIHRlbXBsYXRlIDw+IHN0cnVjdCByYW5rPGludD4geyBlbnVtIHsgdmFsdWUgPSAwIH07IH07CiAgICB0ZW1wbGF0ZSA8PiBzdHJ1Y3QgcmFuazx1bnNpZ25lZD4geyBlbnVtIHsgdmFsdWUgPSAwIH07IH07CiAgICB0ZW1wbGF0ZSA8PiBzdHJ1Y3QgcmFuazxsb25nPiB7IGVudW0geyB2YWx1ZSA9IDEgfTsgfTsKICAgIHRlbXBsYXRlIDw+IHN0cnVjdCByYW5rPHVuc2lnbmVkIGxvbmc+IHsgZW51bSB7IHZhbHVlID0gMSB9OyB9OwogICAgdGVtcGxhdGUgPD4gc3RydWN0IHJhbms8bG9uZyBsb25nPiB7IGVudW0geyB2YWx1ZSA9IDIgfTsgfTsKICAgIHRlbXBsYXRlIDw+IHN0cnVjdCByYW5rPHVuc2lnbmVkIGxvbmcgbG9uZz4geyBlbnVtIHsgdmFsdWUgPSAyIH07IH07CiAgICB0ZW1wbGF0ZSA8PiBzdHJ1Y3QgcmFuazxmbG9hdD4geyBlbnVtIHsgdmFsdWUgPSAzIH07IH07CiAgICB0ZW1wbGF0ZSA8PiBzdHJ1Y3QgcmFuazxkb3VibGU+IHsgZW51bSB7IHZhbHVlID0gNCB9OyB9OwogICAgdGVtcGxhdGUgPD4gc3RydWN0IHJhbms8bG9uZyBkb3VibGU+IHsgZW51bSB7IHZhbHVlID0gNSB9OyB9OwoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZT4gc3RydWN0IG1ha2VfdW5zaWduZWQ7CiAgICB0ZW1wbGF0ZSA8PiBzdHJ1Y3QgbWFrZV91bnNpZ25lZDxpbnQ+IHsgdHlwZWRlZiB1bnNpZ25lZCB0eXBlOyB9OwogICAgdGVtcGxhdGUgPD4gc3RydWN0IG1ha2VfdW5zaWduZWQ8bG9uZz4geyB0eXBlZGVmIHVuc2lnbmVkIGxvbmcgdHlwZTsgfTsKICAgIHRlbXBsYXRlIDw+IHN0cnVjdCBtYWtlX3Vuc2lnbmVkPGxvbmcgbG9uZz4geyB0eXBlZGVmIHVuc2lnbmVkIGxvbmcgbG9uZyB0eXBlOyB9OwoKICAgIHRlbXBsYXRlIDwgdHlwZW5hbWUgQQogICAgICAgICAgICAgLCB0eXBlbmFtZSBCCiAgICAgICAgICAgICAsIGJvb2wgSXNfZnBfb3Jfc2FtZV9zaWduc19vcl9BX2lzX3Vuc2lnbmVkX29yX2JpZ2dlciA+CiAgICBzdHJ1Y3QgY29tbW9uX3R5cGVfaW1wbCB7CiAgICAgICAgdHlwZWRlZiBBIHR5cGU7CiAgICB9OwogICAgdGVtcGxhdGUgPHR5cGVuYW1lIEEsIHR5cGVuYW1lIEI+CiAgICBzdHJ1Y3QgY29tbW9uX3R5cGVfaW1wbDxBLCBCLCBmYWxzZT4KICAgICAgICAgOiBtYWtlX3Vuc2lnbmVkPEE+IHt9OwoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBBLCB0eXBlbmFtZSBCLCBib29sIEFfaXNfaGlnaGVyPgogICAgc3RydWN0IGNvbW1vbl90eXBlX3N3YXAKICAgICAgICAgOiBjb21tb25fdHlwZV9pbXBsPCBBCiAgICAgICAgICAgICAgICAgICAgICAgICAgICwgQgogICAgICAgICAgICAgICAgICAgICAgICAgICAsIGlzX2Zsb2F0aW5nX3BvaW50PEE+Ojp2YWx1ZSB8fCBpc19mbG9hdGluZ19wb2ludDxCPjo6dmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAoaXNfc2lnbmVkPEE+Ojp2YWx1ZSA9PSBpc19zaWduZWQ8Qj46OnZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGlzX3Vuc2lnbmVkPEE+Ojp2YWx1ZSB8fCAoc2l6ZW9mKEEpID4gc2l6ZW9mKEIpKQogICAgICAgICAgICAgICAgICAgICAgICAgICA+IHt9OwogICAgdGVtcGxhdGUgPHR5cGVuYW1lIEEsIHR5cGVuYW1lIEI+CiAgICBzdHJ1Y3QgY29tbW9uX3R5cGVfc3dhcDxBLCBCLCBmYWxzZT4KICAgICAgICAgOiBjb21tb25fdHlwZV9zd2FwPEIsIEEsIHRydWU+IHt9OwoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBBLCB0eXBlbmFtZSBCPgogICAgc3RydWN0IGNvbW1vbl90eXBlCiAgICAgICAgIDogY29tbW9uX3R5cGVfc3dhcDxBLCBCLCAocmFuazxBPjo6dmFsdWUgPiByYW5rPEI+Ojp2YWx1ZSk+IHt9Owp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgQSwgdHlwZW5hbWUgQj4Kc3RydWN0IGNvbW1vbl90eXBlCiAgICAgOiBkZXRhaWw6OmNvbW1vbl90eXBlPCB0eXBlbmFtZSBkZXRhaWw6OnByb21vdGU8QT46OnR5cGUKICAgICAgICAgICAgICAgICAgICAgICAgICAsIHR5cGVuYW1lIGRldGFpbDo6cHJvbW90ZTxCPjo6dHlwZSA+IHt9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEEsIHR5cGVuYW1lIEI+CnZvaWQgdGVzdCgpIHsKCXVzaW5nIGNvbW1vbl90eXBlID0gdHlwZW5hbWUgY29tbW9uX3R5cGU8QSwgQj46OnR5cGU7Cgl1c2luZyBzdW1fdHlwZSA9IGRlY2x0eXBlKEF7fSArIEJ7fSk7CglzdGF0aWNfYXNzZXJ0KHN0ZDo6aXNfc2FtZTxjb21tb25fdHlwZSwgc3VtX3R5cGU+e30sICIiKTsKfTsKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnZvaWQgdGVzdDIoKSB7Cgl0ZXN0PFQsIGJvb2w+KCk7Cgl0ZXN0PFQsIGNoYXI+KCk7Cgl0ZXN0PFQsIHNpZ25lZCBjaGFyPigpOwoJdGVzdDxULCB1bnNpZ25lZCBjaGFyPigpOwoJdGVzdDxULCBzaG9ydD4oKTsKCXRlc3Q8VCwgdW5zaWduZWQgc2hvcnQ+KCk7Cgl0ZXN0PFQsIGludD4oKTsKCXRlc3Q8VCwgdW5zaWduZWQ+KCk7Cgl0ZXN0PFQsIGxvbmc+KCk7Cgl0ZXN0PFQsIHVuc2lnbmVkIGxvbmc+KCk7Cgl0ZXN0PFQsIGxvbmcgbG9uZz4oKTsKCXRlc3Q8VCwgdW5zaWduZWQgbG9uZyBsb25nPigpOwoJdGVzdDxULCBmbG9hdD4oKTsKCXRlc3Q8VCwgZG91YmxlPigpOwoJdGVzdDxULCBsb25nIGRvdWJsZT4oKTsKfTsKaW50IG1haW4oKSB7Cgl0ZXN0Mjxib29sPigpOwoJdGVzdDI8Y2hhcj4oKTsKCXRlc3QyPHNpZ25lZCBjaGFyPigpOwoJdGVzdDI8dW5zaWduZWQgY2hhcj4oKTsKCXRlc3QyPHNob3J0PigpOwoJdGVzdDI8dW5zaWduZWQgc2hvcnQ+KCk7Cgl0ZXN0MjxpbnQ+KCk7Cgl0ZXN0Mjx1bnNpZ25lZD4oKTsKCXRlc3QyPGxvbmc+KCk7Cgl0ZXN0Mjx1bnNpZ25lZCBsb25nPigpOwoJdGVzdDI8bG9uZyBsb25nPigpOwoJdGVzdDI8dW5zaWduZWQgbG9uZyBsb25nPigpOwoJdGVzdDI8ZmxvYXQ+KCk7Cgl0ZXN0Mjxkb3VibGU+KCk7Cgl0ZXN0Mjxsb25nIGRvdWJsZT4oKTsKfQ==