xref: /aosp_15_r20/external/abseil-cpp/absl/container/internal/hash_function_defaults_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
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 
TEST(Eq,Int32)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 
TEST(Hash,Int32)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 
TEST(Eq,Enum)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 
TEST(Hash,Enum)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 
TYPED_TEST(EqString,Works)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 
TYPED_TEST(HashString,Works)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 
TEST(BasicStringViewTest,WStringEqWorks)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 
TEST(BasicStringViewTest,WStringViewEqWorks)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 
TEST(BasicStringViewTest,U16StringEqWorks)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 
TEST(BasicStringViewTest,U16StringViewEqWorks)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 
TEST(BasicStringViewTest,U32StringEqWorks)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 
TEST(BasicStringViewTest,U32StringViewEqWorks)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 
TEST(BasicStringViewTest,WStringHashWorks)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 
TEST(BasicStringViewTest,WStringViewHashWorks)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 
TEST(BasicStringViewTest,U16StringHashWorks)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 
TEST(BasicStringViewTest,U16StringViewHashWorks)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 
TEST(BasicStringViewTest,U32StringHashWorks)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 
TEST(BasicStringViewTest,U32StringViewHashWorks)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>
operator ()absl::container_internal::__anon2074b2980111::NoDeleter284   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 
TYPED_TEST(EqPointer,Works)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 
TEST(Hash,DerivedAndBase)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 
TEST(Hash,FunctionPointer)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 
TYPED_TEST(HashPointer,Works)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 
TEST(EqCord,Works)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 
TEST(HashCord,Works)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 
NoOpReleaser(absl::string_view data,void * arg)414 void NoOpReleaser(absl::string_view data, void* arg) {}
415 
TEST(HashCord,FragmentedCordWorks)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 
TEST(HashCord,FragmentedLongCordWorks)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 
TEST(HashCord,RandomCord)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 
TYPED_TEST(StringLikeTest,Eq)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 
TYPED_TEST(StringLikeTest,NotEq)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 
TYPED_TEST(StringLikeTest,HashEq)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 
operator ()absl::container_internal::__anon2074b2980111::TypeWithAbslContainerHash::absl_container_hash506     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.
operator ()absl::container_internal::__anon2074b2980111::TypeWithAbslContainerHash::absl_container_hash511     size_t operator()(int value) const { return absl::HashOf(value); }
512   };
513 
operator ==(const TypeWithAbslContainerHash & lhs,const TypeWithAbslContainerHash & rhs)514   friend bool operator==(const TypeWithAbslContainerHash& lhs,
515                          const TypeWithAbslContainerHash& rhs) {
516     return lhs.value == rhs.value;
517   }
518 
operator ==(const TypeWithAbslContainerHash & lhs,int rhs)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 
operator ()absl::container_internal::__anon2074b2980111::TypeWithAbslContainerHashAndEq::absl_container_hash531     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.
operator ()absl::container_internal::__anon2074b2980111::TypeWithAbslContainerHashAndEq::absl_container_hash536     size_t operator()(int value) const { return absl::HashOf(value); }
537   };
538 
539   struct absl_container_eq {
540     using is_transparent = void;
541 
operator ()absl::container_internal::__anon2074b2980111::TypeWithAbslContainerHashAndEq::absl_container_eq542     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.
operator ()absl::container_internal::__anon2074b2980111::TypeWithAbslContainerHashAndEq::absl_container_eq548     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 
TYPED_TEST(AbslContainerHashTest,HasherWorks)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 
TYPED_TEST(AbslContainerHashTest,EqWorks)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 
TYPED_TEST(AbslContainerHashTest,HeterogeneityInMapWorks)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 
TYPED_TEST(AbslContainerHashTest,HeterogeneityInSetWorks)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 {
HashableByHashable653   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>
operator ()std::hash661   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>
Hash(const T & v)673 size_t Hash(const T& v) {
674   return hash_default_hash<T>()(v);
675 }
676 
TEST(Delegate,HashDispatch)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
685