Add hasher specializations for enums, pairs and tuples
[folly.git] / folly / Hash.h
index 566bad05afed814ec77e4698711d250ff518f643..f40f4ec27d620512239a7d85fa6f7cac83600863 100644 (file)
@@ -23,6 +23,7 @@
 #include <utility>
 #include <tuple>
 
+#include <folly/ApplyTuple.h>
 #include <folly/SpookyHashV1.h>
 #include <folly/SpookyHashV2.h>
 
@@ -335,7 +336,7 @@ inline uint32_t hsieh_hash32_str(const std::string& str) {
 
 } // namespace hash
 
-template<class Key>
+template<class Key, class Enable = void>
 struct hasher;
 
 struct Hash {
@@ -343,6 +344,11 @@ struct Hash {
   size_t operator()(const T& v) const {
     return hasher<T>()(v);
   }
+
+  template <class T, class... Ts>
+  size_t operator()(const T& t, const Ts&... ts) const {
+    return hash::hash_128_to_64((*this)(t), (*this)(ts...));
+  }
 };
 
 template<> struct hasher<int32_t> {
@@ -369,6 +375,27 @@ template<> struct hasher<uint64_t> {
   }
 };
 
+template <class T>
+struct hasher<T, typename std::enable_if<std::is_enum<T>::value, void>::type> {
+  size_t operator()(T key) const {
+    return Hash()(static_cast<typename std::underlying_type<T>::type>(key));
+  }
+};
+
+template <class T1, class T2>
+struct hasher<std::pair<T1, T2>> {
+  size_t operator()(const std::pair<T1, T2>& key) const {
+    return Hash()(key.first, key.second);
+  }
+};
+
+template <typename... Ts>
+struct hasher<std::tuple<Ts...>> {
+  size_t operator() (const std::tuple<Ts...>& key) const {
+    return applyTuple(Hash(), key);
+  }
+};
+
 // recursion
 template <size_t index, typename... Ts>
 struct TupleHasher {