#include<iostream>
#include<type_traits>
namespace CHECK
{
struct No {};
template<typename T, typename Arg> No operator== (const T&, const Arg&);
template<typename T, typename Arg = T>
struct EqualExists
{
enum { value = !std::is_same<decltype(*(T*)(0) == *(Arg*)(0)), No>::value };
};
}
struct A
{
bool operator == (A const &);
};
struct B
{
short operator == (B const &);
};
struct C {};
struct D
{
short operator == (short);
};
int main()
{
std::cout<< "A::operator== () exists: " << CHECK::EqualExists<A>::value << std::endl;
std::cout<< "B::operator== () exists: " << CHECK::EqualExists<B>::value << std::endl;
std::cout<< "C::operator== () exists: " << CHECK::EqualExists<C>::value << std::endl;
std::cout<< "C::operator== (short) exists: " << CHECK::EqualExists<D, short>::value << std::endl;
}
I2luY2x1ZGU8aW9zdHJlYW0+CiNpbmNsdWRlPHR5cGVfdHJhaXRzPgoKbmFtZXNwYWNlIENIRUNLCnsKICBzdHJ1Y3QgTm8ge307IAogIHRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZz4gTm8gb3BlcmF0b3I9PSAoY29uc3QgVCYsIGNvbnN0IEFyZyYpOwoKICB0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBBcmcgPSBUPgogIHN0cnVjdCBFcXVhbEV4aXN0cwogIHsKICAgIGVudW0geyB2YWx1ZSA9ICFzdGQ6OmlzX3NhbWU8ZGVjbHR5cGUoKihUKikoMCkgPT0gKihBcmcqKSgwKSksIE5vPjo6dmFsdWUgfTsKICB9OyAgCn0KCnN0cnVjdCBBIAp7IAogIGJvb2wgb3BlcmF0b3IgPT0gKEEgY29uc3QgJik7Cn07CgpzdHJ1Y3QgQiAKewogIHNob3J0IG9wZXJhdG9yID09IChCIGNvbnN0ICYpOyAKfTsKCnN0cnVjdCBDIHt9OwoKc3RydWN0IEQKewogIHNob3J0IG9wZXJhdG9yID09IChzaG9ydCk7Cn07CgppbnQgbWFpbigpCnsKICBzdGQ6OmNvdXQ8PCAiQTo6b3BlcmF0b3I9PSAoKSBleGlzdHM6ICIgPDwgQ0hFQ0s6OkVxdWFsRXhpc3RzPEE+Ojp2YWx1ZSA8PCBzdGQ6OmVuZGw7CiAgc3RkOjpjb3V0PDwgIkI6Om9wZXJhdG9yPT0gKCkgZXhpc3RzOiAiIDw8IENIRUNLOjpFcXVhbEV4aXN0czxCPjo6dmFsdWUgPDwgc3RkOjplbmRsOwogIHN0ZDo6Y291dDw8ICJDOjpvcGVyYXRvcj09ICgpIGV4aXN0czogIiA8PCBDSEVDSzo6RXF1YWxFeGlzdHM8Qz46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsKICBzdGQ6OmNvdXQ8PCAiQzo6b3BlcmF0b3I9PSAoc2hvcnQpIGV4aXN0czogIiA8PCBDSEVDSzo6RXF1YWxFeGlzdHM8RCwgc2hvcnQ+Ojp2YWx1ZSA8PCBzdGQ6OmVuZGw7Cn0K