#include <type_traits>
#include <utility>
#include <iostream>
template <typename T, typename = void>
struct Comparator
{
int operator()(const T& a, const T& b) const
{
std::cout << "catch all\n";
if (a < b)
{
return -1;
}
if (a > b)
{
return 1;
}
return 0;
}
};
template <typename T>
struct Comparator<T, std::enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value>>
{
int operator()(const T &a, const T &b) const
{
std::cout << "Signed arithmetic type\n";
return a - b;
}
};
template<typename T>
int comparator(const T& a, const T& b)
{
return Comparator<T>()(a, b);
}
int main()
{
comparator(42, 0);
comparator('c', 'g');
comparator(42u, 0u);
comparator(42LL, 0LL);
comparator(std::string("b"), std::string("a"));
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lID0gdm9pZD4Kc3RydWN0IENvbXBhcmF0b3IKewoJaW50IG9wZXJhdG9yKCkoY29uc3QgVCYgYSwgY29uc3QgVCYgYikgY29uc3QKCXsKCSAgICBzdGQ6OmNvdXQgPDwgImNhdGNoIGFsbFxuIjsKCSAgICBpZiAoYSA8IGIpCgkgICAgewogICAgICAgIAlyZXR1cm4gLTE7CiAgICAJfQogICAgCWlmIChhID4gYikKICAgIAl7CiAgICAgICAgCXJldHVybiAxOwogICAgCX0KICAgIAlyZXR1cm4gMDsKCX0KfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgQ29tcGFyYXRvcjxULCBzdGQ6OmVuYWJsZV9pZl90PHN0ZDo6aXNfaW50ZWdyYWw8VD46OnZhbHVlICYmIHN0ZDo6aXNfc2lnbmVkPFQ+Ojp2YWx1ZT4+CnsKCWludCBvcGVyYXRvcigpKGNvbnN0IFQgJmEsIGNvbnN0IFQgJmIpIGNvbnN0Cgl7CgkgICAgc3RkOjpjb3V0IDw8ICJTaWduZWQgYXJpdGhtZXRpYyB0eXBlXG4iOwoJICAgIHJldHVybiBhIC0gYjsKCX0KfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CmludCBjb21wYXJhdG9yKGNvbnN0IFQmIGEsIGNvbnN0IFQmIGIpCnsKICAgIHJldHVybiBDb21wYXJhdG9yPFQ+KCkoYSwgYik7Cn0KCmludCBtYWluKCkKewogICAgY29tcGFyYXRvcig0MiwgMCk7CiAgICBjb21wYXJhdG9yKCdjJywgJ2cnKTsKICAgIGNvbXBhcmF0b3IoNDJ1LCAwdSk7CiAgICBjb21wYXJhdG9yKDQyTEwsIDBMTCk7CiAgICBjb21wYXJhdG9yKHN0ZDo6c3RyaW5nKCJiIiksIHN0ZDo6c3RyaW5nKCJhIikpOwp9