add folly:hasher<bool>
authorDen Raskovalov <denplusplus@fb.com>
Thu, 9 Feb 2017 20:00:33 +0000 (12:00 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Thu, 9 Feb 2017 20:08:20 +0000 (12:08 -0800)
Summary:
hasher<bool> is a trivial thing, but it is useful, if we implement a hash function for a class by writing something like:
  return folly::Hash()(boolField1_, boolField2_, intField3_, boolField4_, someField5_)

Reviewed By: ot

Differential Revision: D4535563

fbshipit-source-id: 5e6672c2eeaebbbac80a8a066a6a0ec4838810f4

folly/Hash.h
folly/test/HashTest.cpp

index a2fb67992bb98fdd59e4da7e0defd8ea7fded5b8..0f0afc5baf71ac4c4ca301becf5f84e98fca6da5 100644 (file)
@@ -361,6 +361,14 @@ struct Hash {
   }
 };
 
+template <>
+struct hasher<bool> {
+  size_t operator()(bool key) const {
+    // Make sure that all the output bits depend on the input.
+    return -static_cast<size_t>(key);
+  }
+};
+
 template<> struct hasher<int32_t> {
   size_t operator()(int32_t key) const {
     return hash::jenkins_rev_mix32(uint32_t(key));
index 847d3bb898f29ea1f6dc956de865efabd45f376b..7e6bcdf0573944f35748903a2f7cfa479c0c1cd3 100644 (file)
@@ -229,6 +229,39 @@ TEST(Hash, hash_combine) {
   EXPECT_NE(hash_combine(1, 2), hash_combine(2, 1));
 }
 
+TEST(Hash, hash_bool) {
+  const auto hash = folly::Hash();
+  EXPECT_NE(hash(true), hash(false));
+}
+
+TEST(Hash, hash_bool10) {
+  const auto hash = folly::Hash();
+  std::set<size_t> values;
+  for (bool b1 : {false, true}) {
+    for (bool b2 : {false, true}) {
+      for (bool b3 : {false, true}) {
+        for (bool b4 : {false, true}) {
+          for (bool b5 : {false, true}) {
+            for (bool b6 : {false, true}) {
+              for (bool b7 : {false, true}) {
+                for (bool b8 : {false, true}) {
+                  for (bool b9 : {false, true}) {
+                    for (bool b10 : {false, true}) {
+                      values.insert(
+                          hash(b1, b2, b3, b4, b5, b6, b7, b8, b9, b10));
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  EXPECT_EQ(values.size(), 1 << 10);
+}
+
 TEST(Hash, std_tuple) {
   typedef std::tuple<int64_t, std::string, int32_t> tuple3;
   tuple3 t(42, "foo", 1);