From: Den Raskovalov Date: Thu, 9 Feb 2017 20:00:33 +0000 (-0800) Subject: add folly:hasher X-Git-Tag: v2017.03.06.00~44 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=3751f5de62022e0833496c18bdb757a81d0ed3ab;p=folly.git add folly:hasher Summary: hasher 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 --- diff --git a/folly/Hash.h b/folly/Hash.h index a2fb6799..0f0afc5b 100644 --- a/folly/Hash.h +++ b/folly/Hash.h @@ -361,6 +361,14 @@ struct Hash { } }; +template <> +struct hasher { + size_t operator()(bool key) const { + // Make sure that all the output bits depend on the input. + return -static_cast(key); + } +}; + template<> struct hasher { size_t operator()(int32_t key) const { return hash::jenkins_rev_mix32(uint32_t(key)); diff --git a/folly/test/HashTest.cpp b/folly/test/HashTest.cpp index 847d3bb8..7e6bcdf0 100644 --- a/folly/test/HashTest.cpp +++ b/folly/test/HashTest.cpp @@ -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 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 tuple3; tuple3 t(42, "foo", 1);