#include <unordered_set>
struct RIGHT128 {
uint64_t X;
uint64_t Y;
RIGHT128() : X(0), Y(0) {};
RIGHT128(const uint64_t& x, const uint64_t& y) : X(x), Y(y) {};
RIGHT128(const RIGHT128& other) {
X = other.X;
Y = other.Y;
};
RIGHT128& operator=(const RIGHT128& other) {
X = other.X;
Y = other.Y;
return *this;
};
bool operator==(const RIGHT128& other) {
if (X == other.X && Y == other.Y)
return true;
return false;
};
bool operator<(const RIGHT128& other) {
if (X < other.X)
return true;
else if (X == other.X && Y == other.Y)
return true;
return false;
};
// this could be moved in to std::hash<Point>::operator()
size_t operator()(const RIGHT128& RIGHT128ToHash) const noexcept {
size_t hash = RIGHT128ToHash.X + 10 * RIGHT128ToHash.Y;
return hash;
};
};
namespace std {
template<> struct hash<RIGHT128>
{
std::size_t operator()(const RIGHT128& p) const noexcept
{
return p(p);
}
};
}
int main()
{
// no need to specify the hasher if std::hash<Point> exists
std::unordered_set<RIGHT128> p;
return 0;
}
CiNpbmNsdWRlIDx1bm9yZGVyZWRfc2V0PgoKc3RydWN0IFJJR0hUMTI4IHsKCXVpbnQ2NF90IFg7Cgl1aW50NjRfdCBZOwoKCVJJR0hUMTI4KCkgOiBYKDApLCBZKDApIHt9OwoJUklHSFQxMjgoY29uc3QgdWludDY0X3QmIHgsIGNvbnN0IHVpbnQ2NF90JiB5KSA6IFgoeCksIFkoeSkge307CglSSUdIVDEyOChjb25zdCBSSUdIVDEyOCYgb3RoZXIpIHsKCQlYID0gb3RoZXIuWDsKCQlZID0gb3RoZXIuWTsKCX07CgoJUklHSFQxMjgmIG9wZXJhdG9yPShjb25zdCBSSUdIVDEyOCYgb3RoZXIpIHsKCQlYID0gb3RoZXIuWDsKCQlZID0gb3RoZXIuWTsKCQlyZXR1cm4gKnRoaXM7Cgl9OwoKCWJvb2wgb3BlcmF0b3I9PShjb25zdCBSSUdIVDEyOCYgb3RoZXIpIHsKCQlpZiAoWCA9PSBvdGhlci5YICYmIFkgPT0gb3RoZXIuWSkKCQkJcmV0dXJuIHRydWU7CgkJcmV0dXJuIGZhbHNlOwoJfTsKCglib29sIG9wZXJhdG9yPChjb25zdCBSSUdIVDEyOCYgb3RoZXIpIHsKCQlpZiAoWCA8IG90aGVyLlgpCgkJCXJldHVybiB0cnVlOwoJCWVsc2UgaWYgKFggPT0gb3RoZXIuWCAmJiBZID09IG90aGVyLlkpCgkJCXJldHVybiB0cnVlOwoKCQlyZXR1cm4gZmFsc2U7Cgl9OwoKCS8vIHRoaXMgY291bGQgYmUgbW92ZWQgaW4gdG8gc3RkOjpoYXNoPFBvaW50Pjo6b3BlcmF0b3IoKQoJc2l6ZV90IG9wZXJhdG9yKCkoY29uc3QgUklHSFQxMjgmIFJJR0hUMTI4VG9IYXNoKSBjb25zdCBub2V4Y2VwdCB7CgkJc2l6ZV90IGhhc2ggPSBSSUdIVDEyOFRvSGFzaC5YICsgMTAgKiBSSUdIVDEyOFRvSGFzaC5ZOwoJCXJldHVybiBoYXNoOwoJfTsKCn07CgpuYW1lc3BhY2Ugc3RkIHsKCXRlbXBsYXRlPD4gc3RydWN0IGhhc2g8UklHSFQxMjg+Cgl7CgkJc3RkOjpzaXplX3QJb3BlcmF0b3IoKShjb25zdCBSSUdIVDEyOCYgcCkgY29uc3Qgbm9leGNlcHQKCQl7CgkJCXJldHVybiBwKHApOwoJCX0KCX07Cn0KCmludCBtYWluKCkKewogICAgLy8gbm8gbmVlZCB0byBzcGVjaWZ5IHRoZSBoYXNoZXIgaWYgc3RkOjpoYXNoPFBvaW50PiBleGlzdHMKCXN0ZDo6dW5vcmRlcmVkX3NldDxSSUdIVDEyOD4gcDsKCXJldHVybiAwOwp9