tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

hash_function_defaults_test.cc (19335B)


      1 // Copyright 2018 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "absl/container/internal/hash_function_defaults.h"
     16 
     17 #include <cstddef>
     18 #include <functional>
     19 #include <type_traits>
     20 #include <utility>
     21 
     22 #include "gtest/gtest.h"
     23 #include "absl/container/flat_hash_map.h"
     24 #include "absl/container/flat_hash_set.h"
     25 #include "absl/hash/hash.h"
     26 #include "absl/random/random.h"
     27 #include "absl/strings/cord.h"
     28 #include "absl/strings/cord_test_helpers.h"
     29 #include "absl/strings/string_view.h"
     30 
     31 #ifdef ABSL_HAVE_STD_STRING_VIEW
     32 #include <string_view>
     33 #endif
     34 
     35 namespace absl {
     36 ABSL_NAMESPACE_BEGIN
     37 namespace container_internal {
     38 namespace {
     39 
     40 using ::testing::Types;
     41 
     42 TEST(Eq, Int32) {
     43  hash_default_eq<int32_t> eq;
     44  EXPECT_TRUE(eq(1, 1u));
     45  EXPECT_TRUE(eq(1, char{1}));
     46  EXPECT_TRUE(eq(1, true));
     47  EXPECT_TRUE(eq(1, double{1.1}));
     48  EXPECT_FALSE(eq(1, char{2}));
     49  EXPECT_FALSE(eq(1, 2u));
     50  EXPECT_FALSE(eq(1, false));
     51  EXPECT_FALSE(eq(1, 2.));
     52 }
     53 
     54 TEST(Hash, Int32) {
     55  hash_default_hash<int32_t> hash;
     56  auto h = hash(1);
     57  EXPECT_EQ(h, hash(1u));
     58  EXPECT_EQ(h, hash(char{1}));
     59  EXPECT_EQ(h, hash(true));
     60  EXPECT_EQ(h, hash(double{1.1}));
     61  EXPECT_NE(h, hash(2u));
     62  EXPECT_NE(h, hash(char{2}));
     63  EXPECT_NE(h, hash(false));
     64  EXPECT_NE(h, hash(2.));
     65 }
     66 
     67 enum class MyEnum { A, B, C, D };
     68 
     69 TEST(Eq, Enum) {
     70  hash_default_eq<MyEnum> eq;
     71  EXPECT_TRUE(eq(MyEnum::A, MyEnum::A));
     72  EXPECT_FALSE(eq(MyEnum::A, MyEnum::B));
     73 }
     74 
     75 TEST(Hash, Enum) {
     76  hash_default_hash<MyEnum> hash;
     77 
     78  for (MyEnum e : {MyEnum::A, MyEnum::B, MyEnum::C}) {
     79    auto h = hash(e);
     80    EXPECT_EQ(h, hash_default_hash<int>{}(static_cast<int>(e)));
     81    EXPECT_NE(h, hash(MyEnum::D));
     82  }
     83 }
     84 
     85 using StringTypes = ::testing::Types<std::string, absl::string_view>;
     86 
     87 template <class T>
     88 struct EqString : ::testing::Test {
     89  hash_default_eq<T> key_eq;
     90 };
     91 
     92 TYPED_TEST_SUITE(EqString, StringTypes);
     93 
     94 template <class T>
     95 struct HashString : ::testing::Test {
     96  hash_default_hash<T> hasher;
     97 };
     98 
     99 TYPED_TEST_SUITE(HashString, StringTypes);
    100 
    101 TYPED_TEST(EqString, Works) {
    102  auto eq = this->key_eq;
    103  EXPECT_TRUE(eq("a", "a"));
    104  EXPECT_TRUE(eq("a", absl::string_view("a")));
    105  EXPECT_TRUE(eq("a", std::string("a")));
    106  EXPECT_FALSE(eq("a", "b"));
    107  EXPECT_FALSE(eq("a", absl::string_view("b")));
    108  EXPECT_FALSE(eq("a", std::string("b")));
    109 }
    110 
    111 TYPED_TEST(HashString, Works) {
    112  auto hash = this->hasher;
    113  auto h = hash("a");
    114  EXPECT_EQ(h, hash(absl::string_view("a")));
    115  EXPECT_EQ(h, hash(std::string("a")));
    116  EXPECT_NE(h, hash(absl::string_view("b")));
    117  EXPECT_NE(h, hash(std::string("b")));
    118 }
    119 
    120 TEST(BasicStringViewTest, WStringEqWorks) {
    121 #ifndef ABSL_HAVE_STD_STRING_VIEW
    122  GTEST_SKIP();
    123 #else
    124  hash_default_eq<std::wstring> eq;
    125  EXPECT_TRUE(eq(L"a", L"a"));
    126  EXPECT_TRUE(eq(L"a", std::wstring_view(L"a")));
    127  EXPECT_TRUE(eq(L"a", std::wstring(L"a")));
    128  EXPECT_FALSE(eq(L"a", L"b"));
    129  EXPECT_FALSE(eq(L"a", std::wstring_view(L"b")));
    130  EXPECT_FALSE(eq(L"a", std::wstring(L"b")));
    131 #endif
    132 }
    133 
    134 TEST(BasicStringViewTest, WStringViewEqWorks) {
    135 #ifndef ABSL_HAVE_STD_STRING_VIEW
    136  GTEST_SKIP();
    137 #else
    138  hash_default_eq<std::wstring_view> eq;
    139  EXPECT_TRUE(eq(L"a", L"a"));
    140  EXPECT_TRUE(eq(L"a", std::wstring_view(L"a")));
    141  EXPECT_TRUE(eq(L"a", std::wstring(L"a")));
    142  EXPECT_FALSE(eq(L"a", L"b"));
    143  EXPECT_FALSE(eq(L"a", std::wstring_view(L"b")));
    144  EXPECT_FALSE(eq(L"a", std::wstring(L"b")));
    145 #endif
    146 }
    147 
    148 TEST(BasicStringViewTest, U16StringEqWorks) {
    149 #ifndef ABSL_HAVE_STD_STRING_VIEW
    150  GTEST_SKIP();
    151 #else
    152  hash_default_eq<std::u16string> eq;
    153  EXPECT_TRUE(eq(u"a", u"a"));
    154  EXPECT_TRUE(eq(u"a", std::u16string_view(u"a")));
    155  EXPECT_TRUE(eq(u"a", std::u16string(u"a")));
    156  EXPECT_FALSE(eq(u"a", u"b"));
    157  EXPECT_FALSE(eq(u"a", std::u16string_view(u"b")));
    158  EXPECT_FALSE(eq(u"a", std::u16string(u"b")));
    159 #endif
    160 }
    161 
    162 TEST(BasicStringViewTest, U16StringViewEqWorks) {
    163 #ifndef ABSL_HAVE_STD_STRING_VIEW
    164  GTEST_SKIP();
    165 #else
    166  hash_default_eq<std::u16string_view> eq;
    167  EXPECT_TRUE(eq(u"a", u"a"));
    168  EXPECT_TRUE(eq(u"a", std::u16string_view(u"a")));
    169  EXPECT_TRUE(eq(u"a", std::u16string(u"a")));
    170  EXPECT_FALSE(eq(u"a", u"b"));
    171  EXPECT_FALSE(eq(u"a", std::u16string_view(u"b")));
    172  EXPECT_FALSE(eq(u"a", std::u16string(u"b")));
    173 #endif
    174 }
    175 
    176 TEST(BasicStringViewTest, U32StringEqWorks) {
    177 #ifndef ABSL_HAVE_STD_STRING_VIEW
    178  GTEST_SKIP();
    179 #else
    180  hash_default_eq<std::u32string> eq;
    181  EXPECT_TRUE(eq(U"a", U"a"));
    182  EXPECT_TRUE(eq(U"a", std::u32string_view(U"a")));
    183  EXPECT_TRUE(eq(U"a", std::u32string(U"a")));
    184  EXPECT_FALSE(eq(U"a", U"b"));
    185  EXPECT_FALSE(eq(U"a", std::u32string_view(U"b")));
    186  EXPECT_FALSE(eq(U"a", std::u32string(U"b")));
    187 #endif
    188 }
    189 
    190 TEST(BasicStringViewTest, U32StringViewEqWorks) {
    191 #ifndef ABSL_HAVE_STD_STRING_VIEW
    192  GTEST_SKIP();
    193 #else
    194  hash_default_eq<std::u32string_view> eq;
    195  EXPECT_TRUE(eq(U"a", U"a"));
    196  EXPECT_TRUE(eq(U"a", std::u32string_view(U"a")));
    197  EXPECT_TRUE(eq(U"a", std::u32string(U"a")));
    198  EXPECT_FALSE(eq(U"a", U"b"));
    199  EXPECT_FALSE(eq(U"a", std::u32string_view(U"b")));
    200  EXPECT_FALSE(eq(U"a", std::u32string(U"b")));
    201 #endif
    202 }
    203 
    204 TEST(BasicStringViewTest, WStringHashWorks) {
    205 #ifndef ABSL_HAVE_STD_STRING_VIEW
    206  GTEST_SKIP();
    207 #else
    208  hash_default_hash<std::wstring> hash;
    209  auto h = hash(L"a");
    210  EXPECT_EQ(h, hash(std::wstring_view(L"a")));
    211  EXPECT_EQ(h, hash(std::wstring(L"a")));
    212  EXPECT_NE(h, hash(std::wstring_view(L"b")));
    213  EXPECT_NE(h, hash(std::wstring(L"b")));
    214 #endif
    215 }
    216 
    217 TEST(BasicStringViewTest, WStringViewHashWorks) {
    218 #ifndef ABSL_HAVE_STD_STRING_VIEW
    219  GTEST_SKIP();
    220 #else
    221  hash_default_hash<std::wstring_view> hash;
    222  auto h = hash(L"a");
    223  EXPECT_EQ(h, hash(std::wstring_view(L"a")));
    224  EXPECT_EQ(h, hash(std::wstring(L"a")));
    225  EXPECT_NE(h, hash(std::wstring_view(L"b")));
    226  EXPECT_NE(h, hash(std::wstring(L"b")));
    227 #endif
    228 }
    229 
    230 TEST(BasicStringViewTest, U16StringHashWorks) {
    231 #ifndef ABSL_HAVE_STD_STRING_VIEW
    232  GTEST_SKIP();
    233 #else
    234  hash_default_hash<std::u16string> hash;
    235  auto h = hash(u"a");
    236  EXPECT_EQ(h, hash(std::u16string_view(u"a")));
    237  EXPECT_EQ(h, hash(std::u16string(u"a")));
    238  EXPECT_NE(h, hash(std::u16string_view(u"b")));
    239  EXPECT_NE(h, hash(std::u16string(u"b")));
    240 #endif
    241 }
    242 
    243 TEST(BasicStringViewTest, U16StringViewHashWorks) {
    244 #ifndef ABSL_HAVE_STD_STRING_VIEW
    245  GTEST_SKIP();
    246 #else
    247  hash_default_hash<std::u16string_view> hash;
    248  auto h = hash(u"a");
    249  EXPECT_EQ(h, hash(std::u16string_view(u"a")));
    250  EXPECT_EQ(h, hash(std::u16string(u"a")));
    251  EXPECT_NE(h, hash(std::u16string_view(u"b")));
    252  EXPECT_NE(h, hash(std::u16string(u"b")));
    253 #endif
    254 }
    255 
    256 TEST(BasicStringViewTest, U32StringHashWorks) {
    257 #ifndef ABSL_HAVE_STD_STRING_VIEW
    258  GTEST_SKIP();
    259 #else
    260  hash_default_hash<std::u32string> hash;
    261  auto h = hash(U"a");
    262  EXPECT_EQ(h, hash(std::u32string_view(U"a")));
    263  EXPECT_EQ(h, hash(std::u32string(U"a")));
    264  EXPECT_NE(h, hash(std::u32string_view(U"b")));
    265  EXPECT_NE(h, hash(std::u32string(U"b")));
    266 #endif
    267 }
    268 
    269 TEST(BasicStringViewTest, U32StringViewHashWorks) {
    270 #ifndef ABSL_HAVE_STD_STRING_VIEW
    271  GTEST_SKIP();
    272 #else
    273  hash_default_hash<std::u32string_view> hash;
    274  auto h = hash(U"a");
    275  EXPECT_EQ(h, hash(std::u32string_view(U"a")));
    276  EXPECT_EQ(h, hash(std::u32string(U"a")));
    277  EXPECT_NE(h, hash(std::u32string_view(U"b")));
    278  EXPECT_NE(h, hash(std::u32string(U"b")));
    279 #endif
    280 }
    281 
    282 struct NoDeleter {
    283  template <class T>
    284  void operator()(const T* ptr) const {}
    285 };
    286 
    287 using PointerTypes =
    288    ::testing::Types<const int*, int*, std::unique_ptr<const int>,
    289                     std::unique_ptr<const int, NoDeleter>,
    290                     std::unique_ptr<int>, std::unique_ptr<int, NoDeleter>,
    291                     std::shared_ptr<const int>, std::shared_ptr<int>>;
    292 
    293 template <class T>
    294 struct EqPointer : ::testing::Test {
    295  hash_default_eq<T> key_eq;
    296 };
    297 
    298 TYPED_TEST_SUITE(EqPointer, PointerTypes);
    299 
    300 template <class T>
    301 struct HashPointer : ::testing::Test {
    302  hash_default_hash<T> hasher;
    303 };
    304 
    305 TYPED_TEST_SUITE(HashPointer, PointerTypes);
    306 
    307 TYPED_TEST(EqPointer, Works) {
    308  int dummy;
    309  auto eq = this->key_eq;
    310  auto sptr = std::make_shared<int>();
    311  std::shared_ptr<const int> csptr = sptr;
    312  int* ptr = sptr.get();
    313  const int* cptr = ptr;
    314  std::unique_ptr<int, NoDeleter> uptr(ptr);
    315  std::unique_ptr<const int, NoDeleter> cuptr(ptr);
    316 
    317  EXPECT_TRUE(eq(ptr, cptr));
    318  EXPECT_TRUE(eq(ptr, sptr));
    319  EXPECT_TRUE(eq(ptr, uptr));
    320  EXPECT_TRUE(eq(ptr, csptr));
    321  EXPECT_TRUE(eq(ptr, cuptr));
    322  EXPECT_FALSE(eq(&dummy, cptr));
    323  EXPECT_FALSE(eq(&dummy, sptr));
    324  EXPECT_FALSE(eq(&dummy, uptr));
    325  EXPECT_FALSE(eq(&dummy, csptr));
    326  EXPECT_FALSE(eq(&dummy, cuptr));
    327 }
    328 
    329 TEST(Hash, DerivedAndBase) {
    330  struct Base {};
    331  struct Derived : Base {};
    332 
    333  hash_default_hash<Base*> hasher;
    334 
    335  Base base;
    336  Derived derived;
    337  EXPECT_NE(hasher(&base), hasher(&derived));
    338  EXPECT_EQ(hasher(static_cast<Base*>(&derived)), hasher(&derived));
    339 
    340  auto dp = std::make_shared<Derived>();
    341  EXPECT_EQ(hasher(static_cast<Base*>(dp.get())), hasher(dp));
    342 }
    343 
    344 TEST(Hash, FunctionPointer) {
    345  using Func = int (*)();
    346  hash_default_hash<Func> hasher;
    347  hash_default_eq<Func> eq;
    348 
    349  Func p1 = [] { return 1; }, p2 = [] { return 2; };
    350  EXPECT_EQ(hasher(p1), hasher(p1));
    351  EXPECT_TRUE(eq(p1, p1));
    352 
    353  EXPECT_NE(hasher(p1), hasher(p2));
    354  EXPECT_FALSE(eq(p1, p2));
    355 }
    356 
    357 TYPED_TEST(HashPointer, Works) {
    358  int dummy;
    359  auto hash = this->hasher;
    360  auto sptr = std::make_shared<int>();
    361  std::shared_ptr<const int> csptr = sptr;
    362  int* ptr = sptr.get();
    363  const int* cptr = ptr;
    364  std::unique_ptr<int, NoDeleter> uptr(ptr);
    365  std::unique_ptr<const int, NoDeleter> cuptr(ptr);
    366 
    367  EXPECT_EQ(hash(ptr), hash(cptr));
    368  EXPECT_EQ(hash(ptr), hash(sptr));
    369  EXPECT_EQ(hash(ptr), hash(uptr));
    370  EXPECT_EQ(hash(ptr), hash(csptr));
    371  EXPECT_EQ(hash(ptr), hash(cuptr));
    372  EXPECT_NE(hash(&dummy), hash(cptr));
    373  EXPECT_NE(hash(&dummy), hash(sptr));
    374  EXPECT_NE(hash(&dummy), hash(uptr));
    375  EXPECT_NE(hash(&dummy), hash(csptr));
    376  EXPECT_NE(hash(&dummy), hash(cuptr));
    377 }
    378 
    379 TEST(EqCord, Works) {
    380  hash_default_eq<absl::Cord> eq;
    381  const absl::string_view a_string_view = "a";
    382  const absl::Cord a_cord(a_string_view);
    383  const absl::string_view b_string_view = "b";
    384  const absl::Cord b_cord(b_string_view);
    385 
    386  EXPECT_TRUE(eq(a_cord, a_cord));
    387  EXPECT_TRUE(eq(a_cord, a_string_view));
    388  EXPECT_TRUE(eq(a_string_view, a_cord));
    389  EXPECT_FALSE(eq(a_cord, b_cord));
    390  EXPECT_FALSE(eq(a_cord, b_string_view));
    391  EXPECT_FALSE(eq(b_string_view, a_cord));
    392 }
    393 
    394 TEST(HashCord, Works) {
    395  hash_default_hash<absl::Cord> hash;
    396  const absl::string_view a_string_view = "a";
    397  const absl::Cord a_cord(a_string_view);
    398  const absl::string_view b_string_view = "b";
    399  const absl::Cord b_cord(b_string_view);
    400 
    401  EXPECT_EQ(hash(a_cord), hash(a_cord));
    402  EXPECT_EQ(hash(b_cord), hash(b_cord));
    403  EXPECT_EQ(hash(a_string_view), hash(a_cord));
    404  EXPECT_EQ(hash(b_string_view), hash(b_cord));
    405  EXPECT_EQ(hash(absl::Cord("")), hash(""));
    406  EXPECT_EQ(hash(absl::Cord()), hash(absl::string_view()));
    407 
    408  EXPECT_NE(hash(a_cord), hash(b_cord));
    409  EXPECT_NE(hash(a_cord), hash(b_string_view));
    410  EXPECT_NE(hash(a_string_view), hash(b_cord));
    411  EXPECT_NE(hash(a_string_view), hash(b_string_view));
    412 }
    413 
    414 void NoOpReleaser(absl::string_view data, void* arg) {}
    415 
    416 TEST(HashCord, FragmentedCordWorks) {
    417  hash_default_hash<absl::Cord> hash;
    418  absl::Cord c = absl::MakeFragmentedCord({"a", "b", "c"});
    419  EXPECT_FALSE(c.TryFlat().has_value());
    420  EXPECT_EQ(hash(c), hash("abc"));
    421 }
    422 
    423 TEST(HashCord, FragmentedLongCordWorks) {
    424  hash_default_hash<absl::Cord> hash;
    425  // Crete some large strings which do not fit on the stack.
    426  std::string a(65536, 'a');
    427  std::string b(65536, 'b');
    428  absl::Cord c = absl::MakeFragmentedCord({a, b});
    429  EXPECT_FALSE(c.TryFlat().has_value());
    430  EXPECT_EQ(hash(c), hash(a + b));
    431 }
    432 
    433 TEST(HashCord, RandomCord) {
    434  hash_default_hash<absl::Cord> hash;
    435  auto bitgen = absl::BitGen();
    436  for (int i = 0; i < 1000; ++i) {
    437    const int number_of_segments = absl::Uniform(bitgen, 0, 10);
    438    std::vector<std::string> pieces;
    439    for (size_t s = 0; s < number_of_segments; ++s) {
    440      std::string str;
    441      str.resize(absl::Uniform(bitgen, 0, 4096));
    442      // MSVC needed the explicit return type in the lambda.
    443      std::generate(str.begin(), str.end(), [&]() -> char {
    444        return static_cast<char>(absl::Uniform<unsigned char>(bitgen));
    445      });
    446      pieces.push_back(str);
    447    }
    448    absl::Cord c = absl::MakeFragmentedCord(pieces);
    449    EXPECT_EQ(hash(c), hash(std::string(c)));
    450  }
    451 }
    452 
    453 // Cartesian product of (std::string, absl::string_view)
    454 // with (std::string, absl::string_view, const char*, absl::Cord).
    455 using StringTypesCartesianProduct = Types<
    456    // clang-format off
    457    std::pair<absl::Cord, std::string>,
    458    std::pair<absl::Cord, absl::string_view>,
    459    std::pair<absl::Cord, absl::Cord>,
    460    std::pair<absl::Cord, const char*>,
    461 
    462    std::pair<std::string, absl::Cord>,
    463    std::pair<absl::string_view, absl::Cord>,
    464 
    465    std::pair<absl::string_view, std::string>,
    466    std::pair<absl::string_view, absl::string_view>,
    467    std::pair<absl::string_view, const char*>>;
    468 // clang-format on
    469 
    470 constexpr char kFirstString[] = "abc123";
    471 constexpr char kSecondString[] = "ijk456";
    472 
    473 template <typename T>
    474 struct StringLikeTest : public ::testing::Test {
    475  typename T::first_type a1{kFirstString};
    476  typename T::second_type b1{kFirstString};
    477  typename T::first_type a2{kSecondString};
    478  typename T::second_type b2{kSecondString};
    479  hash_default_eq<typename T::first_type> eq;
    480  hash_default_hash<typename T::first_type> hash;
    481 };
    482 
    483 TYPED_TEST_SUITE(StringLikeTest, StringTypesCartesianProduct);
    484 
    485 TYPED_TEST(StringLikeTest, Eq) {
    486  EXPECT_TRUE(this->eq(this->a1, this->b1));
    487  EXPECT_TRUE(this->eq(this->b1, this->a1));
    488 }
    489 
    490 TYPED_TEST(StringLikeTest, NotEq) {
    491  EXPECT_FALSE(this->eq(this->a1, this->b2));
    492  EXPECT_FALSE(this->eq(this->b2, this->a1));
    493 }
    494 
    495 TYPED_TEST(StringLikeTest, HashEq) {
    496  EXPECT_EQ(this->hash(this->a1), this->hash(this->b1));
    497  EXPECT_EQ(this->hash(this->a2), this->hash(this->b2));
    498  // It would be a poor hash function which collides on these strings.
    499  EXPECT_NE(this->hash(this->a1), this->hash(this->b2));
    500 }
    501 
    502 struct TypeWithAbslContainerHash {
    503  struct absl_container_hash {
    504    using is_transparent = void;
    505 
    506    size_t operator()(const TypeWithAbslContainerHash& foo) const {
    507      return absl::HashOf(foo.value);
    508    }
    509 
    510    // Extra overload to test that heterogeneity works for this hasher.
    511    size_t operator()(int value) const { return absl::HashOf(value); }
    512  };
    513 
    514  friend bool operator==(const TypeWithAbslContainerHash& lhs,
    515                         const TypeWithAbslContainerHash& rhs) {
    516    return lhs.value == rhs.value;
    517  }
    518 
    519  friend bool operator==(const TypeWithAbslContainerHash& lhs, int rhs) {
    520    return lhs.value == rhs;
    521  }
    522 
    523  int value;
    524  int noise;
    525 };
    526 
    527 struct TypeWithAbslContainerHashAndEq {
    528  struct absl_container_hash {
    529    using is_transparent = void;
    530 
    531    size_t operator()(const TypeWithAbslContainerHashAndEq& foo) const {
    532      return absl::HashOf(foo.value);
    533    }
    534 
    535    // Extra overload to test that heterogeneity works for this hasher.
    536    size_t operator()(int value) const { return absl::HashOf(value); }
    537  };
    538 
    539  struct absl_container_eq {
    540    using is_transparent = void;
    541 
    542    bool operator()(const TypeWithAbslContainerHashAndEq& lhs,
    543                    const TypeWithAbslContainerHashAndEq& rhs) const {
    544      return lhs.value == rhs.value;
    545    }
    546 
    547    // Extra overload to test that heterogeneity works for this eq.
    548    bool operator()(const TypeWithAbslContainerHashAndEq& lhs, int rhs) const {
    549      return lhs.value == rhs;
    550    }
    551  };
    552 
    553  template <typename T>
    554  bool operator==(T&& other) const = delete;
    555 
    556  int value;
    557  int noise;
    558 };
    559 
    560 using AbslContainerHashTypes =
    561    Types<TypeWithAbslContainerHash, TypeWithAbslContainerHashAndEq>;
    562 
    563 template <typename T>
    564 using AbslContainerHashTest = ::testing::Test;
    565 
    566 TYPED_TEST_SUITE(AbslContainerHashTest, AbslContainerHashTypes);
    567 
    568 TYPED_TEST(AbslContainerHashTest, HasherWorks) {
    569  hash_default_hash<TypeParam> hasher;
    570 
    571  TypeParam foo1{/*value=*/1, /*noise=*/100};
    572  TypeParam foo1_copy{/*value=*/1, /*noise=*/20};
    573  TypeParam foo2{/*value=*/2, /*noise=*/100};
    574 
    575  EXPECT_EQ(hasher(foo1), absl::HashOf(1));
    576  EXPECT_EQ(hasher(foo2), absl::HashOf(2));
    577  EXPECT_EQ(hasher(foo1), hasher(foo1_copy));
    578 
    579  // Heterogeneity works.
    580  EXPECT_EQ(hasher(foo1), hasher(1));
    581  EXPECT_EQ(hasher(foo2), hasher(2));
    582 }
    583 
    584 TYPED_TEST(AbslContainerHashTest, EqWorks) {
    585  hash_default_eq<TypeParam> eq;
    586 
    587  TypeParam foo1{/*value=*/1, /*noise=*/100};
    588  TypeParam foo1_copy{/*value=*/1, /*noise=*/20};
    589  TypeParam foo2{/*value=*/2, /*noise=*/100};
    590 
    591  EXPECT_TRUE(eq(foo1, foo1_copy));
    592  EXPECT_FALSE(eq(foo1, foo2));
    593 
    594  // Heterogeneity works.
    595  EXPECT_TRUE(eq(foo1, 1));
    596  EXPECT_FALSE(eq(foo1, 2));
    597 }
    598 
    599 TYPED_TEST(AbslContainerHashTest, HeterogeneityInMapWorks) {
    600  absl::flat_hash_map<TypeParam, int> map;
    601 
    602  TypeParam foo1{/*value=*/1, /*noise=*/100};
    603  TypeParam foo1_copy{/*value=*/1, /*noise=*/20};
    604  TypeParam foo2{/*value=*/2, /*noise=*/100};
    605  TypeParam foo3{/*value=*/3, /*noise=*/100};
    606 
    607  map[foo1] = 1;
    608  map[foo2] = 2;
    609 
    610  EXPECT_TRUE(map.contains(foo1_copy));
    611  EXPECT_EQ(map.at(foo1_copy), 1);
    612  EXPECT_TRUE(map.contains(1));
    613  EXPECT_EQ(map.at(1), 1);
    614  EXPECT_TRUE(map.contains(2));
    615  EXPECT_EQ(map.at(2), 2);
    616  EXPECT_FALSE(map.contains(foo3));
    617  EXPECT_FALSE(map.contains(3));
    618 }
    619 
    620 TYPED_TEST(AbslContainerHashTest, HeterogeneityInSetWorks) {
    621  absl::flat_hash_set<TypeParam> set;
    622 
    623  TypeParam foo1{/*value=*/1, /*noise=*/100};
    624  TypeParam foo1_copy{/*value=*/1, /*noise=*/20};
    625  TypeParam foo2{/*value=*/2, /*noise=*/100};
    626 
    627  set.insert(foo1);
    628 
    629  EXPECT_TRUE(set.contains(foo1_copy));
    630  EXPECT_TRUE(set.contains(1));
    631  EXPECT_FALSE(set.contains(foo2));
    632  EXPECT_FALSE(set.contains(2));
    633 }
    634 
    635 }  // namespace
    636 }  // namespace container_internal
    637 ABSL_NAMESPACE_END
    638 }  // namespace absl
    639 
    640 enum Hash : size_t {
    641  kStd = 0x1,  // std::hash
    642 #ifdef _MSC_VER
    643  kExtension = kStd,  // In MSVC, std::hash == ::hash
    644 #else                 // _MSC_VER
    645  kExtension = 0x2,  // ::hash (GCC extension)
    646 #endif                // _MSC_VER
    647 };
    648 
    649 // H is a bitmask of Hash enumerations.
    650 // Hashable<H> is hashable via all means specified in H.
    651 template <int H>
    652 struct Hashable {
    653  static constexpr bool HashableBy(Hash h) { return h & H; }
    654 };
    655 
    656 namespace std {
    657 template <int H>
    658 struct hash<Hashable<H>> {
    659  template <class E = Hashable<H>,
    660            class = typename std::enable_if<E::HashableBy(kStd)>::type>
    661  size_t operator()(E) const {
    662    return kStd;
    663  }
    664 };
    665 }  // namespace std
    666 
    667 namespace absl {
    668 ABSL_NAMESPACE_BEGIN
    669 namespace container_internal {
    670 namespace {
    671 
    672 template <class T>
    673 size_t Hash(const T& v) {
    674  return hash_default_hash<T>()(v);
    675 }
    676 
    677 TEST(Delegate, HashDispatch) {
    678  EXPECT_EQ(Hash(kStd), Hash(Hashable<kStd>()));
    679 }
    680 
    681 }  // namespace
    682 }  // namespace container_internal
    683 ABSL_NAMESPACE_END
    684 }  // namespace absl