#include <algorithm>
#include <iostream>
#include <functional>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
template<typename Hash, typename Iterator>
size_t order_independent_hash(Iterator begin, Iterator end, Hash hasher)
{
std::vector<size_t> hashes;
for (Iterator it = begin; it != end; ++it)
hashes.push_back(hasher(*it));
std::sort(hashes.begin(), hashes.end());
size_t result = 0;
for (auto it2 = hashes.begin(); it2 != hashes.end(); ++it2)
result ^= *it2 + 0x9e3779b9 + (result<<6) + (result>>2);
return result;
}
namespace std
{
template<typename T1, typename T2>
struct hash<std::pair<T1,T2> >
{
typedef std::pair<T1,T2> argument_type;
typedef std::size_t result_type;
result_type operator()(argument_type const& s) const
{
result_type const h1 ( std::hash<T1>()(s.first) );
result_type const h2 ( std::hash<T2>()(s.second) );
return h1 ^ (h2 + 0x9e3779b9 + (h1<<6) + (h1>>2));
}
};
template<typename Key, typename T>
struct hash<std::unordered_map<Key,T> >
{
typedef std::unordered_map<Key,T> argument_type;
typedef std::size_t result_type;
result_type operator()(argument_type const& s) const
{
return order_independent_hash(s.begin(), s.end(), std::hash<std::pair<Key,T> >());
}
};
}
int main() {
unordered_map<int, string> tester;
tester[1] = "one";
tester[2] = "two";
tester[3] = "three";
tester[4] = "four";
tester[5] = "five";
cout << hash<unordered_map<int, string>>()(tester) << endl;
return 0;
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHVub3JkZXJlZF9tYXA+CiNpbmNsdWRlIDx2ZWN0b3I+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBIYXNoLCB0eXBlbmFtZSBJdGVyYXRvcj4Kc2l6ZV90IG9yZGVyX2luZGVwZW5kZW50X2hhc2goSXRlcmF0b3IgYmVnaW4sIEl0ZXJhdG9yIGVuZCwgSGFzaCBoYXNoZXIpCnsKCXN0ZDo6dmVjdG9yPHNpemVfdD4gaGFzaGVzOwoJZm9yIChJdGVyYXRvciBpdCA9IGJlZ2luOyBpdCAhPSBlbmQ7ICsraXQpCgkJaGFzaGVzLnB1c2hfYmFjayhoYXNoZXIoKml0KSk7CglzdGQ6OnNvcnQoaGFzaGVzLmJlZ2luKCksIGhhc2hlcy5lbmQoKSk7CglzaXplX3QgcmVzdWx0ID0gMDsKCWZvciAoYXV0byBpdDIgPSBoYXNoZXMuYmVnaW4oKTsgaXQyICE9IGhhc2hlcy5lbmQoKTsgKytpdDIpCgkJcmVzdWx0IF49ICppdDIgKyAweDllMzc3OWI5ICsgKHJlc3VsdDw8NikgKyAocmVzdWx0Pj4yKTsKCXJldHVybiByZXN1bHQ7Cn0KCm5hbWVzcGFjZSBzdGQKewoJdGVtcGxhdGU8dHlwZW5hbWUgVDEsIHR5cGVuYW1lIFQyPgoJc3RydWN0IGhhc2g8c3RkOjpwYWlyPFQxLFQyPiA+Cgl7CiAgICAgICAgdHlwZWRlZiBzdGQ6OnBhaXI8VDEsVDI+IGFyZ3VtZW50X3R5cGU7CiAgICAgICAgdHlwZWRlZiBzdGQ6OnNpemVfdCByZXN1bHRfdHlwZTsKIAogICAgICAgIHJlc3VsdF90eXBlIG9wZXJhdG9yKCkoYXJndW1lbnRfdHlwZSBjb25zdCYgcykgY29uc3QKICAgICAgICB7CiAgICAgICAgICAgIHJlc3VsdF90eXBlIGNvbnN0IGgxICggc3RkOjpoYXNoPFQxPigpKHMuZmlyc3QpICk7CiAgICAgICAgICAgIHJlc3VsdF90eXBlIGNvbnN0IGgyICggc3RkOjpoYXNoPFQyPigpKHMuc2Vjb25kKSApOwogICAgICAgICAgICByZXR1cm4gaDEgXiAoaDIgKyAweDllMzc3OWI5ICsgKGgxPDw2KSArIChoMT4+MikpOwogICAgICAgIH0KCX07CgkKCXRlbXBsYXRlPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVD4KCXN0cnVjdCBoYXNoPHN0ZDo6dW5vcmRlcmVkX21hcDxLZXksVD4gPgoJewogICAgICAgIHR5cGVkZWYgc3RkOjp1bm9yZGVyZWRfbWFwPEtleSxUPiBhcmd1bWVudF90eXBlOwogICAgICAgIHR5cGVkZWYgc3RkOjpzaXplX3QgcmVzdWx0X3R5cGU7CiAKICAgICAgICByZXN1bHRfdHlwZSBvcGVyYXRvcigpKGFyZ3VtZW50X3R5cGUgY29uc3QmIHMpIGNvbnN0CiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gb3JkZXJfaW5kZXBlbmRlbnRfaGFzaChzLmJlZ2luKCksIHMuZW5kKCksIHN0ZDo6aGFzaDxzdGQ6OnBhaXI8S2V5LFQ+ID4oKSk7CiAgICAgICAgfQoJfTsKfQoKaW50IG1haW4oKSB7Cgl1bm9yZGVyZWRfbWFwPGludCwgc3RyaW5nPiB0ZXN0ZXI7Cgl0ZXN0ZXJbMV0gPSAib25lIjsKCXRlc3RlclsyXSA9ICJ0d28iOwoJdGVzdGVyWzNdID0gInRocmVlIjsKCXRlc3Rlcls0XSA9ICJmb3VyIjsKCXRlc3Rlcls1XSA9ICJmaXZlIjsKCWNvdXQgPDwgaGFzaDx1bm9yZGVyZWRfbWFwPGludCwgc3RyaW5nPj4oKSh0ZXN0ZXIpIDw8IGVuZGw7CglyZXR1cm4gMDsKfQ==