Specialise std::hash for folly::Optional
authorSebastian Messmer <messmer@fb.com>
Wed, 8 Feb 2017 19:41:13 +0000 (11:41 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Wed, 8 Feb 2017 19:50:22 +0000 (11:50 -0800)
Summary: This allows using folly::Optional<T> in std::unordered_map and std::unordered_set.

Reviewed By: luciang

Differential Revision: D4469938

fbshipit-source-id: b86b1a4510379b337e9de83471a4aafce6d5a6cb

folly/Optional.h
folly/test/OptionalTest.cpp

index 61e71c1f2dc86b3709d1e265b9e72b50c8a487ba..5350b2ee5e44d69c55868c0a96e2e24d286a16fb 100644 (file)
@@ -54,6 +54,7 @@
  *  }
  */
 #include <cstddef>
+#include <functional>
 #include <new>
 #include <stdexcept>
 #include <type_traits>
@@ -418,3 +419,16 @@ template<class V> bool operator> (const V& other, const Optional<V>&) = delete;
 ///////////////////////////////////////////////////////////////////////////////
 
 } // namespace folly
+
+// Allow usage of Optional<T> in std::unordered_map and std::unordered_set
+FOLLY_NAMESPACE_STD_BEGIN
+template <class T>
+struct hash<folly::Optional<T>> {
+  size_t operator()(folly::Optional<T> const& obj) const {
+    if (!obj.hasValue()) {
+      return 0;
+    }
+    return hash<typename remove_const<T>::type>()(*obj);
+  }
+};
+FOLLY_NAMESPACE_STD_END
index 4a0ef9b37c233308384c5a11e305db6fc576d427..3968040f23aa35a65a7b29821128c7bf77b46cbf 100644 (file)
 #include <folly/Portability.h>
 #include <folly/portability/GTest.h>
 
-#include <memory>
-#include <vector>
 #include <algorithm>
 #include <iomanip>
+#include <memory>
 #include <string>
 #include <type_traits>
+#include <unordered_map>
+#include <vector>
 
-#include <glog/logging.h>
 #include <boost/optional.hpp>
 
 using std::unique_ptr;
@@ -545,4 +545,12 @@ TEST(Optional, TriviallyDestructible) {
   EXPECT_TRUE(std::is_trivially_destructible<Optional<int>>::value);
   EXPECT_FALSE(std::is_trivially_destructible<Optional<WithDestructor>>::value);
 }
+
+TEST(Optional, Hash) {
+  // Test it's usable in std::unordered map (compile time check)
+  std::unordered_map<Optional<int>, Optional<int>> obj;
+  // Also check the std::hash template can be instantiated by the compiler
+  std::hash<Optional<int>>()(none);
+  std::hash<Optional<int>>()(3);
+}
 }