#include <cstdint>
#include <iostream>
#include <limits>
#define define_result_type( t1, t2, r )\
template <>\
struct addition_result<t1,t2> {\
typedef r type;\
}
template <typename T1, typename T2>
struct addition_result;
define_result_type(int8_t, int8_t, int16_t);
define_result_type(int16_t, int16_t, int32_t);
define_result_type(int32_t, int32_t, int64_t);
template<typename T1, typename T2>
typename addition_result<T1,T2>::type
add( T1 const & lhs, T2 const & rhs ) {
typedef typename addition_result<T1,T2>::type result_type;
return result_type(lhs) + result_type(rhs);
};
int main() {
using namespace std;
int32_t a, b;
a = b = numeric_limits<decltype(a)>::max();
cout << a + b << endl;
cout << add(a, b) << endl;
}
I2luY2x1ZGUgPGNzdGRpbnQ+CiAKI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bGltaXRzPgogCiNkZWZpbmUgZGVmaW5lX3Jlc3VsdF90eXBlKCB0MSwgdDIsIHIgKVwKdGVtcGxhdGUgPD5cCnN0cnVjdCBhZGRpdGlvbl9yZXN1bHQ8dDEsdDI+IHtcCiAgICB0eXBlZGVmIHIgdHlwZTtcCn0KIAp0ZW1wbGF0ZSA8dHlwZW5hbWUgVDEsIHR5cGVuYW1lIFQyPgpzdHJ1Y3QgYWRkaXRpb25fcmVzdWx0OwogCmRlZmluZV9yZXN1bHRfdHlwZShpbnQ4X3QsIGludDhfdCwgaW50MTZfdCk7CmRlZmluZV9yZXN1bHRfdHlwZShpbnQxNl90LCBpbnQxNl90LCBpbnQzMl90KTsKZGVmaW5lX3Jlc3VsdF90eXBlKGludDMyX3QsIGludDMyX3QsIGludDY0X3QpOwogCnRlbXBsYXRlPHR5cGVuYW1lIFQxLCB0eXBlbmFtZSBUMj4KdHlwZW5hbWUgYWRkaXRpb25fcmVzdWx0PFQxLFQyPjo6dHlwZQphZGQoIFQxIGNvbnN0ICYgbGhzLCBUMiBjb25zdCAmIHJocyApIHsKICAgIHR5cGVkZWYgdHlwZW5hbWUgYWRkaXRpb25fcmVzdWx0PFQxLFQyPjo6dHlwZSByZXN1bHRfdHlwZTsKCiAgICByZXR1cm4gcmVzdWx0X3R5cGUobGhzKSArIHJlc3VsdF90eXBlKHJocyk7Cn07CiAKaW50IG1haW4oKSB7CiAgIHVzaW5nIG5hbWVzcGFjZSBzdGQ7CiAgIAogICBpbnQzMl90IGEsIGI7CiAgIGEgPSBiID0gbnVtZXJpY19saW1pdHM8ZGVjbHR5cGUoYSk+OjptYXgoKTsKCiAgIGNvdXQgPDwgYSArIGIgPDwgZW5kbDsKICAgY291dCA8PCBhZGQoYSwgYikgPDwgZW5kbDsKfQ==