- #include <tuple> 
- #include <cstring> 
- #include <functional> 
- #include <type_traits> 
-   
- size_t hash_combiner(size_t left, size_t right) //replacable 
- { return left^right;} 
-   
- template<int index, class...types> 
- struct hash_impl { 
-     size_t operator()(size_t a, const std::tuple<types...>& t) const { 
-         typedef typename std::tuple_element<index, std::tuple<types...>>::type nexttype; 
-         hash_impl<index-1, types...> next; 
-         size_t b = std::hash<nexttype>()(std::get<index>(t)); 
-         return next(hash_combiner(a, b), t);  
-     } 
- }; 
- template<class...types> 
- struct hash_impl<0, types...> { 
-     size_t operator()(size_t a, const std::tuple<types...>& t) const { 
-         typedef typename std::tuple_element<0, std::tuple<types...>>::type nexttype; 
-         size_t b = std::hash<nexttype>()(std::get<0>(t)); 
-         return hash_combiner(a, b);  
-     } 
- }; 
-   
- namespace std { 
-     template<class...types> 
-     struct hash<std::tuple<types...>> { 
-         size_t operator()(const std::tuple<types...>& t) { 
-             const size_t begin = std::tuple_size<std::tuple<types...>>::value-1; 
-             return hash_impl<begin, types...>()(1, t); //1 should be some largervalue 
-         } 
-     }; 
- } 
-   
- #include <iostream> 
-   
- int main() { 
-     typedef std::tuple<int, char, float> T; 
-     T t(14, 'A', 3.14); 
-     std::cout << std::hash<T>()(t); 
-     return 0; 
- } 
				I2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8Y3N0cmluZz4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KIApzaXplX3QgaGFzaF9jb21iaW5lcihzaXplX3QgbGVmdCwgc2l6ZV90IHJpZ2h0KSAvL3JlcGxhY2FibGUKeyByZXR1cm4gbGVmdF5yaWdodDt9CiAKdGVtcGxhdGU8aW50IGluZGV4LCBjbGFzcy4uLnR5cGVzPgpzdHJ1Y3QgaGFzaF9pbXBsIHsKICAgIHNpemVfdCBvcGVyYXRvcigpKHNpemVfdCBhLCBjb25zdCBzdGQ6OnR1cGxlPHR5cGVzLi4uPiYgdCkgY29uc3QgewogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgc3RkOjp0dXBsZV9lbGVtZW50PGluZGV4LCBzdGQ6OnR1cGxlPHR5cGVzLi4uPj46OnR5cGUgbmV4dHR5cGU7CiAgICAgICAgaGFzaF9pbXBsPGluZGV4LTEsIHR5cGVzLi4uPiBuZXh0OwogICAgICAgIHNpemVfdCBiID0gc3RkOjpoYXNoPG5leHR0eXBlPigpKHN0ZDo6Z2V0PGluZGV4Pih0KSk7CiAgICAgICAgcmV0dXJuIG5leHQoaGFzaF9jb21iaW5lcihhLCBiKSwgdCk7IAogICAgfQp9Owp0ZW1wbGF0ZTxjbGFzcy4uLnR5cGVzPgpzdHJ1Y3QgaGFzaF9pbXBsPDAsIHR5cGVzLi4uPiB7CiAgICBzaXplX3Qgb3BlcmF0b3IoKShzaXplX3QgYSwgY29uc3Qgc3RkOjp0dXBsZTx0eXBlcy4uLj4mIHQpIGNvbnN0IHsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIHN0ZDo6dHVwbGVfZWxlbWVudDwwLCBzdGQ6OnR1cGxlPHR5cGVzLi4uPj46OnR5cGUgbmV4dHR5cGU7CiAgICAgICAgc2l6ZV90IGIgPSBzdGQ6Omhhc2g8bmV4dHR5cGU+KCkoc3RkOjpnZXQ8MD4odCkpOwogICAgICAgIHJldHVybiBoYXNoX2NvbWJpbmVyKGEsIGIpOyAKICAgIH0KfTsKCm5hbWVzcGFjZSBzdGQgewogICAgdGVtcGxhdGU8Y2xhc3MuLi50eXBlcz4KICAgIHN0cnVjdCBoYXNoPHN0ZDo6dHVwbGU8dHlwZXMuLi4+PiB7CiAgICAgICAgc2l6ZV90IG9wZXJhdG9yKCkoY29uc3Qgc3RkOjp0dXBsZTx0eXBlcy4uLj4mIHQpIHsKICAgICAgICAgICAgY29uc3Qgc2l6ZV90IGJlZ2luID0gc3RkOjp0dXBsZV9zaXplPHN0ZDo6dHVwbGU8dHlwZXMuLi4+Pjo6dmFsdWUtMTsKICAgICAgICAgICAgcmV0dXJuIGhhc2hfaW1wbDxiZWdpbiwgdHlwZXMuLi4+KCkoMSwgdCk7IC8vMSBzaG91bGQgYmUgc29tZSBsYXJnZXJ2YWx1ZQogICAgICAgIH0KICAgIH07Cn0KCiNpbmNsdWRlIDxpb3N0cmVhbT4KIAppbnQgbWFpbigpIHsKICAgIHR5cGVkZWYgc3RkOjp0dXBsZTxpbnQsIGNoYXIsIGZsb2F0PiBUOwogICAgVCB0KDE0LCAnQScsIDMuMTQpOwogICAgc3RkOjpjb3V0IDw8IHN0ZDo6aGFzaDxUPigpKHQpOwogICAgcmV0dXJuIDA7Cn0=