about summary refs log tree commit diff
path: root/absl/hash
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2019-03-06T19·36-0800
committerDerek Mauro <dmauro@google.com>2019-03-06T19·49-0500
commitfebc5ee6a92d0eb7dac1fceaa6c648cf6521b4dc (patch)
treefcca391395791680a80a559f7efd9c47da6ff305 /absl/hash
parent9fdf5e5b805412cb2a2e624d3e9a11588120465f (diff)
Export of internal Abseil changes.
--
f9f068aa8a260dc576398e47b8e4540902e41358 by Derek Mauro <dmauro@google.com>:

Fix test string with embedded NUL. Currently parses as octal.

PiperOrigin-RevId: 237088193

--
d271ffdd3f450f817f6d30e98ff39d439aaf3a98 by Abseil Team <absl-team@google.com>:

Make symbolizer examine any mapping with read+exec permission regardless of 'w' bit.

PiperOrigin-RevId: 237056461

--
af315f8306d36a7367a452fd0b58cafdbf20719d by Abseil Team <absl-team@google.com>:

Switch comments referencing base:: CondVar and Mutex to absl::.

PiperOrigin-RevId: 236917884

--
c624d5d1c0bdb917bff5e651ba40599472f84e0e by Gennadiy Rozental <rogeeff@google.com>:

Internal change

PiperOrigin-RevId: 236898300

--
3cdc82429af964846d1152f49148abc61d196a4b by Samuel Benzaquen <sbenza@google.com>:

Make the `long double` overload if AbslHashValue a template to avoid invalid
conversions with implicit operators.

This overload was never meant to capture anything other than `long double` and any current caller to it that wasn't a `long double` is potentially a bug.
In particular, any type with an implicit `bool` conversion is calling this
overload instead of trying to find a hash<> specialization, thus causing
pretty bad hash behavior.

PiperOrigin-RevId: 236877073
GitOrigin-RevId: f9f068aa8a260dc576398e47b8e4540902e41358
Change-Id: If9cc008dd814f0ca06ed881f612c06575f1f7137
Diffstat (limited to 'absl/hash')
-rw-r--r--absl/hash/hash.h2
-rw-r--r--absl/hash/hash_test.cc24
-rw-r--r--absl/hash/hash_testing.h4
-rw-r--r--absl/hash/internal/hash.h9
-rw-r--r--absl/hash/internal/spy_hash_state.h4
5 files changed, 33 insertions, 10 deletions
diff --git a/absl/hash/hash.h b/absl/hash/hash.h
index 36c7c2b3b6d2..3b1d6eab71e3 100644
--- a/absl/hash/hash.h
+++ b/absl/hash/hash.h
@@ -243,7 +243,7 @@ using Hash = absl::hash_internal::Hash<T>;
 //       absl::HashState::combine(std::move(state), v1_, v2_);
 //     }
 //     int v1_;
-//     string v2_;
+//     std::string v2_;
 //   };
 class HashState : public hash_internal::HashStateBase<HashState> {
  public:
diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc
index 2c9e46b76223..97c3449ae78d 100644
--- a/absl/hash/hash_test.cc
+++ b/absl/hash/hash_test.cc
@@ -275,7 +275,6 @@ struct WrapInTuple {
 
 TEST(HashValueTest, Strings) {
   EXPECT_TRUE((is_hashable<std::string>::value));
-  EXPECT_TRUE((is_hashable<std::string>::value));
 
   const std::string small = "foo";
   const std::string dup = "foofoo";
@@ -705,7 +704,8 @@ TEST(HashTest, HashNonUniquelyRepresentedType) {
 }
 
 TEST(HashTest, StandardHashContainerUsage) {
-  std::unordered_map<int, std::string, Hash<int>> map = {{0, "foo"}, { 42, "bar" }};
+  std::unordered_map<int, std::string, Hash<int>> map = {{0, "foo"},
+                                                         {42, "bar"}};
 
   EXPECT_NE(map.find(0), map.end());
   EXPECT_EQ(map.find(1), map.end());
@@ -775,4 +775,24 @@ TEST(HashTest, TypeErased) {
             SpyHash(std::make_pair(size_t{7}, 17)));
 }
 
+struct ValueWithBoolConversion {
+  operator bool() const { return false; }
+  int i;
+};
+
+}  // namespace
+namespace std {
+template <>
+struct hash<ValueWithBoolConversion> {
+  size_t operator()(ValueWithBoolConversion v) { return v.i; }
+};
+}  // namespace std
+
+namespace {
+
+TEST(HashTest, DoesNotUseImplicitConversionsToBool) {
+  EXPECT_NE(absl::Hash<ValueWithBoolConversion>()(ValueWithBoolConversion{0}),
+            absl::Hash<ValueWithBoolConversion>()(ValueWithBoolConversion{1}));
+}
+
 }  // namespace
diff --git a/absl/hash/hash_testing.h b/absl/hash/hash_testing.h
index 52bcb55a20f5..06d0949912be 100644
--- a/absl/hash/hash_testing.h
+++ b/absl/hash/hash_testing.h
@@ -190,7 +190,9 @@ VerifyTypeImplementsAbslHashCorrectly(const Container& values, Eq equals) {
   struct Info {
     const V& value;
     size_t index;
-    std::string ToString() const { return absl::visit(PrintVisitor{index}, value); }
+    std::string ToString() const {
+      return absl::visit(PrintVisitor{index}, value);
+    }
     SpyHashState expand() const { return absl::visit(ExpandVisitor{}, value); }
   };
 
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h
index bd07677a796d..4db816c71083 100644
--- a/absl/hash/internal/hash.h
+++ b/absl/hash/internal/hash.h
@@ -221,7 +221,9 @@ typename std::enable_if<std::is_enum<Enum>::value, H>::type AbslHashValue(
 }
 // AbslHashValue() for hashing floating-point values
 template <typename H, typename Float>
-typename std::enable_if<std::is_floating_point<Float>::value, H>::type
+typename std::enable_if<std::is_same<Float, float>::value ||
+                            std::is_same<Float, double>::value,
+                        H>::type
 AbslHashValue(H hash_state, Float value) {
   return hash_internal::hash_bytes(std::move(hash_state),
                                    value == 0 ? 0 : value);
@@ -231,8 +233,9 @@ AbslHashValue(H hash_state, Float value) {
 // For example, in x86 sizeof(long double)==16 but it only really uses 80-bits
 // of it. This means we can't use hash_bytes on a long double and have to
 // convert it to something else first.
-template <typename H>
-H AbslHashValue(H hash_state, long double value) {
+template <typename H, typename LongDouble>
+typename std::enable_if<std::is_same<LongDouble, long double>::value, H>::type
+AbslHashValue(H hash_state, LongDouble value) {
   const int category = std::fpclassify(value);
   switch (category) {
     case FP_INFINITE:
diff --git a/absl/hash/internal/spy_hash_state.h b/absl/hash/internal/spy_hash_state.h
index e7d1dfef37ee..102e05de96b1 100644
--- a/absl/hash/internal/spy_hash_state.h
+++ b/absl/hash/internal/spy_hash_state.h
@@ -39,8 +39,7 @@ namespace hash_internal {
 template <typename T>
 class SpyHashStateImpl : public HashStateBase<SpyHashStateImpl<T>> {
  public:
-  SpyHashStateImpl()
-      : error_(std::make_shared<absl::optional<std::string>>()) {
+  SpyHashStateImpl() : error_(std::make_shared<absl::optional<std::string>>()) {
     static_assert(std::is_void<T>::value, "");
   }
 
@@ -170,7 +169,6 @@ class SpyHashStateImpl : public HashStateBase<SpyHashStateImpl<T>> {
   // AbslHashValue directly (because the hash state type does not match).
   static bool direct_absl_hash_value_error_;
 
-
   std::vector<std::string> hash_representation_;
   // This is a shared_ptr because we want all instances of the particular
   // SpyHashState run to share the field. This way we can set the error for