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