#include <iostream>
#include <type_traits>
namespace details
{
template <typename T, typename R, typename = R>
struct equality : std::false_type {};
template <typename T, typename R>
struct equality<T, R, decltype(std::declval<T>() == std::declval<T>())> : std::true_type {};
}
template<typename T, typename R = bool>
struct equality : details::equality<T, R> {};
struct A {};
struct B { bool operator == (B const &); };
struct C { short operator == (C const &); };
struct D { bool operator == (short); };
int main()
{
std::cout<< "equality<A>::value = " << equality<A>::value << std::endl;
std::cout<< "equality<B>::value = " << equality<B>::value << std::endl;
std::cout<< "equality<C>::value = " << equality<C>::value << std::endl;
std::cout<< "equality<B,short>::value = " << equality<B,short>::value << std::endl;
std::cout<< "equality<C,short>::value = " << equality<C,short>::value << std::endl;
std::cout<< "equality<D>::value = " << equality<D>::value << "<====\n";
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgpuYW1lc3BhY2UgZGV0YWlscwp7CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgUiwgdHlwZW5hbWUgPSBSPgogICAgc3RydWN0IGVxdWFsaXR5IDogc3RkOjpmYWxzZV90eXBlIHt9OwogICAgICAgIAogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFI+CiAgICBzdHJ1Y3QgZXF1YWxpdHk8VCwgUiwgZGVjbHR5cGUoc3RkOjpkZWNsdmFsPFQ+KCkgPT0gc3RkOjpkZWNsdmFsPFQ+KCkpPiA6IHN0ZDo6dHJ1ZV90eXBlIHt9Owp9CiAgICAKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgUiA9IGJvb2w+CnN0cnVjdCBlcXVhbGl0eSA6IGRldGFpbHM6OmVxdWFsaXR5PFQsIFI+IHt9OwoKc3RydWN0IEEgIHt9OwpzdHJ1Y3QgQiAgeyAgYm9vbCBvcGVyYXRvciA9PSAoQiBjb25zdCAmKTsgfTsKc3RydWN0IEMgIHsgIHNob3J0IG9wZXJhdG9yID09IChDIGNvbnN0ICYpOyB9OwpzdHJ1Y3QgRCAgeyAgYm9vbCBvcGVyYXRvciA9PSAoc2hvcnQpOyB9OwoKaW50IG1haW4oKQp7CiAgICBzdGQ6OmNvdXQ8PCAiZXF1YWxpdHk8QT46OnZhbHVlID0gIiA8PCBlcXVhbGl0eTxBPjo6dmFsdWUgPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0PDwgImVxdWFsaXR5PEI+Ojp2YWx1ZSA9ICIgPDwgZXF1YWxpdHk8Qj46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dDw8ICJlcXVhbGl0eTxDPjo6dmFsdWUgPSAiIDw8IGVxdWFsaXR5PEM+Ojp2YWx1ZSA8PCBzdGQ6OmVuZGw7CiAgICBzdGQ6OmNvdXQ8PCAiZXF1YWxpdHk8QixzaG9ydD46OnZhbHVlID0gIiA8PCBlcXVhbGl0eTxCLHNob3J0Pjo6dmFsdWUgPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0PDwgImVxdWFsaXR5PEMsc2hvcnQ+Ojp2YWx1ZSA9ICIgPDwgZXF1YWxpdHk8QyxzaG9ydD46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dDw8ICJlcXVhbGl0eTxEPjo6dmFsdWUgPSAiIDw8IGVxdWFsaXR5PEQ+Ojp2YWx1ZSA8PCAiPD09PT1cbiI7Cn0=