• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <functional>
18 #include <type_traits>
19 #include <utility>
20 
21 #include "gtest/gtest.h"
22 #include "absl/random/random.h"
23 #include "absl/strings/cord.h"
24 #include "absl/strings/cord_test_helpers.h"
25 #include "absl/strings/string_view.h"
26 
27 #ifdef ABSL_HAVE_STD_STRING_VIEW
28 #include <string_view>
29 #endif
30 
31 namespace absl {
32 ABSL_NAMESPACE_BEGIN
33 namespace container_internal {
34 namespace {
35 
36 using ::testing::Types;
37 
TEST(Eq,Int32)38 TEST(Eq, Int32) {
39   hash_default_eq<int32_t> eq;
40   EXPECT_TRUE(eq(1, 1u));
41   EXPECT_TRUE(eq(1, char{1}));
42   EXPECT_TRUE(eq(1, true));
43   EXPECT_TRUE(eq(1, double{1.1}));
44   EXPECT_FALSE(eq(1, char{2}));
45   EXPECT_FALSE(eq(1, 2u));
46   EXPECT_FALSE(eq(1, false));
47   EXPECT_FALSE(eq(1, 2.));
48 }
49 
TEST(Hash,Int32)50 TEST(Hash, Int32) {
51   hash_default_hash<int32_t> hash;
52   auto h = hash(1);
53   EXPECT_EQ(h, hash(1u));
54   EXPECT_EQ(h, hash(char{1}));
55   EXPECT_EQ(h, hash(true));
56   EXPECT_EQ(h, hash(double{1.1}));
57   EXPECT_NE(h, hash(2u));
58   EXPECT_NE(h, hash(char{2}));
59   EXPECT_NE(h, hash(false));
60   EXPECT_NE(h, hash(2.));
61 }
62 
63 enum class MyEnum { A, B, C, D };
64 
TEST(Eq,Enum)65 TEST(Eq, Enum) {
66   hash_default_eq<MyEnum> eq;
67   EXPECT_TRUE(eq(MyEnum::A, MyEnum::A));
68   EXPECT_FALSE(eq(MyEnum::A, MyEnum::B));
69 }
70 
TEST(Hash,Enum)71 TEST(Hash, Enum) {
72   hash_default_hash<MyEnum> hash;
73 
74   for (MyEnum e : {MyEnum::A, MyEnum::B, MyEnum::C}) {
75     auto h = hash(e);
76     EXPECT_EQ(h, hash_default_hash<int>{}(static_cast<int>(e)));
77     EXPECT_NE(h, hash(MyEnum::D));
78   }
79 }
80 
81 using StringTypes = ::testing::Types<std::string, absl::string_view>;
82 
83 template <class T>
84 struct EqString : ::testing::Test {
85   hash_default_eq<T> key_eq;
86 };
87 
88 TYPED_TEST_SUITE(EqString, StringTypes);
89 
90 template <class T>
91 struct HashString : ::testing::Test {
92   hash_default_hash<T> hasher;
93 };
94 
95 TYPED_TEST_SUITE(HashString, StringTypes);
96 
TYPED_TEST(EqString,Works)97 TYPED_TEST(EqString, Works) {
98   auto eq = this->key_eq;
99   EXPECT_TRUE(eq("a", "a"));
100   EXPECT_TRUE(eq("a", absl::string_view("a")));
101   EXPECT_TRUE(eq("a", std::string("a")));
102   EXPECT_FALSE(eq("a", "b"));
103   EXPECT_FALSE(eq("a", absl::string_view("b")));
104   EXPECT_FALSE(eq("a", std::string("b")));
105 }
106 
TYPED_TEST(HashString,Works)107 TYPED_TEST(HashString, Works) {
108   auto hash = this->hasher;
109   auto h = hash("a");
110   EXPECT_EQ(h, hash(absl::string_view("a")));
111   EXPECT_EQ(h, hash(std::string("a")));
112   EXPECT_NE(h, hash(absl::string_view("b")));
113   EXPECT_NE(h, hash(std::string("b")));
114 }
115 
TEST(BasicStringViewTest,WStringEqWorks)116 TEST(BasicStringViewTest, WStringEqWorks) {
117 #ifndef ABSL_HAVE_STD_STRING_VIEW
118   GTEST_SKIP();
119 #else
120   hash_default_eq<std::wstring> eq;
121   EXPECT_TRUE(eq(L"a", L"a"));
122   EXPECT_TRUE(eq(L"a", std::wstring_view(L"a")));
123   EXPECT_TRUE(eq(L"a", std::wstring(L"a")));
124   EXPECT_FALSE(eq(L"a", L"b"));
125   EXPECT_FALSE(eq(L"a", std::wstring_view(L"b")));
126   EXPECT_FALSE(eq(L"a", std::wstring(L"b")));
127 #endif
128 }
129 
TEST(BasicStringViewTest,WStringViewEqWorks)130 TEST(BasicStringViewTest, WStringViewEqWorks) {
131 #ifndef ABSL_HAVE_STD_STRING_VIEW
132   GTEST_SKIP();
133 #else
134   hash_default_eq<std::wstring_view> eq;
135   EXPECT_TRUE(eq(L"a", L"a"));
136   EXPECT_TRUE(eq(L"a", std::wstring_view(L"a")));
137   EXPECT_TRUE(eq(L"a", std::wstring(L"a")));
138   EXPECT_FALSE(eq(L"a", L"b"));
139   EXPECT_FALSE(eq(L"a", std::wstring_view(L"b")));
140   EXPECT_FALSE(eq(L"a", std::wstring(L"b")));
141 #endif
142 }
143 
TEST(BasicStringViewTest,U16StringEqWorks)144 TEST(BasicStringViewTest, U16StringEqWorks) {
145 #ifndef ABSL_HAVE_STD_STRING_VIEW
146   GTEST_SKIP();
147 #else
148   hash_default_eq<std::u16string> eq;
149   EXPECT_TRUE(eq(u"a", u"a"));
150   EXPECT_TRUE(eq(u"a", std::u16string_view(u"a")));
151   EXPECT_TRUE(eq(u"a", std::u16string(u"a")));
152   EXPECT_FALSE(eq(u"a", u"b"));
153   EXPECT_FALSE(eq(u"a", std::u16string_view(u"b")));
154   EXPECT_FALSE(eq(u"a", std::u16string(u"b")));
155 #endif
156 }
157 
TEST(BasicStringViewTest,U16StringViewEqWorks)158 TEST(BasicStringViewTest, U16StringViewEqWorks) {
159 #ifndef ABSL_HAVE_STD_STRING_VIEW
160   GTEST_SKIP();
161 #else
162   hash_default_eq<std::u16string_view> eq;
163   EXPECT_TRUE(eq(u"a", u"a"));
164   EXPECT_TRUE(eq(u"a", std::u16string_view(u"a")));
165   EXPECT_TRUE(eq(u"a", std::u16string(u"a")));
166   EXPECT_FALSE(eq(u"a", u"b"));
167   EXPECT_FALSE(eq(u"a", std::u16string_view(u"b")));
168   EXPECT_FALSE(eq(u"a", std::u16string(u"b")));
169 #endif
170 }
171 
TEST(BasicStringViewTest,U32StringEqWorks)172 TEST(BasicStringViewTest, U32StringEqWorks) {
173 #ifndef ABSL_HAVE_STD_STRING_VIEW
174   GTEST_SKIP();
175 #else
176   hash_default_eq<std::u32string> eq;
177   EXPECT_TRUE(eq(U"a", U"a"));
178   EXPECT_TRUE(eq(U"a", std::u32string_view(U"a")));
179   EXPECT_TRUE(eq(U"a", std::u32string(U"a")));
180   EXPECT_FALSE(eq(U"a", U"b"));
181   EXPECT_FALSE(eq(U"a", std::u32string_view(U"b")));
182   EXPECT_FALSE(eq(U"a", std::u32string(U"b")));
183 #endif
184 }
185 
TEST(BasicStringViewTest,U32StringViewEqWorks)186 TEST(BasicStringViewTest, U32StringViewEqWorks) {
187 #ifndef ABSL_HAVE_STD_STRING_VIEW
188   GTEST_SKIP();
189 #else
190   hash_default_eq<std::u32string_view> eq;
191   EXPECT_TRUE(eq(U"a", U"a"));
192   EXPECT_TRUE(eq(U"a", std::u32string_view(U"a")));
193   EXPECT_TRUE(eq(U"a", std::u32string(U"a")));
194   EXPECT_FALSE(eq(U"a", U"b"));
195   EXPECT_FALSE(eq(U"a", std::u32string_view(U"b")));
196   EXPECT_FALSE(eq(U"a", std::u32string(U"b")));
197 #endif
198 }
199 
TEST(BasicStringViewTest,WStringHashWorks)200 TEST(BasicStringViewTest, WStringHashWorks) {
201 #ifndef ABSL_HAVE_STD_STRING_VIEW
202   GTEST_SKIP();
203 #else
204   hash_default_hash<std::wstring> hash;
205   auto h = hash(L"a");
206   EXPECT_EQ(h, hash(std::wstring_view(L"a")));
207   EXPECT_EQ(h, hash(std::wstring(L"a")));
208   EXPECT_NE(h, hash(std::wstring_view(L"b")));
209   EXPECT_NE(h, hash(std::wstring(L"b")));
210 #endif
211 }
212 
TEST(BasicStringViewTest,WStringViewHashWorks)213 TEST(BasicStringViewTest, WStringViewHashWorks) {
214 #ifndef ABSL_HAVE_STD_STRING_VIEW
215   GTEST_SKIP();
216 #else
217   hash_default_hash<std::wstring_view> hash;
218   auto h = hash(L"a");
219   EXPECT_EQ(h, hash(std::wstring_view(L"a")));
220   EXPECT_EQ(h, hash(std::wstring(L"a")));
221   EXPECT_NE(h, hash(std::wstring_view(L"b")));
222   EXPECT_NE(h, hash(std::wstring(L"b")));
223 #endif
224 }
225 
TEST(BasicStringViewTest,U16StringHashWorks)226 TEST(BasicStringViewTest, U16StringHashWorks) {
227 #ifndef ABSL_HAVE_STD_STRING_VIEW
228   GTEST_SKIP();
229 #else
230   hash_default_hash<std::u16string> hash;
231   auto h = hash(u"a");
232   EXPECT_EQ(h, hash(std::u16string_view(u"a")));
233   EXPECT_EQ(h, hash(std::u16string(u"a")));
234   EXPECT_NE(h, hash(std::u16string_view(u"b")));
235   EXPECT_NE(h, hash(std::u16string(u"b")));
236 #endif
237 }
238 
TEST(BasicStringViewTest,U16StringViewHashWorks)239 TEST(BasicStringViewTest, U16StringViewHashWorks) {
240 #ifndef ABSL_HAVE_STD_STRING_VIEW
241   GTEST_SKIP();
242 #else
243   hash_default_hash<std::u16string_view> hash;
244   auto h = hash(u"a");
245   EXPECT_EQ(h, hash(std::u16string_view(u"a")));
246   EXPECT_EQ(h, hash(std::u16string(u"a")));
247   EXPECT_NE(h, hash(std::u16string_view(u"b")));
248   EXPECT_NE(h, hash(std::u16string(u"b")));
249 #endif
250 }
251 
TEST(BasicStringViewTest,U32StringHashWorks)252 TEST(BasicStringViewTest, U32StringHashWorks) {
253 #ifndef ABSL_HAVE_STD_STRING_VIEW
254   GTEST_SKIP();
255 #else
256   hash_default_hash<std::u32string> hash;
257   auto h = hash(U"a");
258   EXPECT_EQ(h, hash(std::u32string_view(U"a")));
259   EXPECT_EQ(h, hash(std::u32string(U"a")));
260   EXPECT_NE(h, hash(std::u32string_view(U"b")));
261   EXPECT_NE(h, hash(std::u32string(U"b")));
262 #endif
263 }
264 
TEST(BasicStringViewTest,U32StringViewHashWorks)265 TEST(BasicStringViewTest, U32StringViewHashWorks) {
266 #ifndef ABSL_HAVE_STD_STRING_VIEW
267   GTEST_SKIP();
268 #else
269   hash_default_hash<std::u32string_view> hash;
270   auto h = hash(U"a");
271   EXPECT_EQ(h, hash(std::u32string_view(U"a")));
272   EXPECT_EQ(h, hash(std::u32string(U"a")));
273   EXPECT_NE(h, hash(std::u32string_view(U"b")));
274   EXPECT_NE(h, hash(std::u32string(U"b")));
275 #endif
276 }
277 
278 struct NoDeleter {
279   template <class T>
operator ()absl::container_internal::__anon6dfd19760111::NoDeleter280   void operator()(const T* ptr) const {}
281 };
282 
283 using PointerTypes =
284     ::testing::Types<const int*, int*, std::unique_ptr<const int>,
285                      std::unique_ptr<const int, NoDeleter>,
286                      std::unique_ptr<int>, std::unique_ptr<int, NoDeleter>,
287                      std::shared_ptr<const int>, std::shared_ptr<int>>;
288 
289 template <class T>
290 struct EqPointer : ::testing::Test {
291   hash_default_eq<T> key_eq;
292 };
293 
294 TYPED_TEST_SUITE(EqPointer, PointerTypes);
295 
296 template <class T>
297 struct HashPointer : ::testing::Test {
298   hash_default_hash<T> hasher;
299 };
300 
301 TYPED_TEST_SUITE(HashPointer, PointerTypes);
302 
TYPED_TEST(EqPointer,Works)303 TYPED_TEST(EqPointer, Works) {
304   int dummy;
305   auto eq = this->key_eq;
306   auto sptr = std::make_shared<int>();
307   std::shared_ptr<const int> csptr = sptr;
308   int* ptr = sptr.get();
309   const int* cptr = ptr;
310   std::unique_ptr<int, NoDeleter> uptr(ptr);
311   std::unique_ptr<const int, NoDeleter> cuptr(ptr);
312 
313   EXPECT_TRUE(eq(ptr, cptr));
314   EXPECT_TRUE(eq(ptr, sptr));
315   EXPECT_TRUE(eq(ptr, uptr));
316   EXPECT_TRUE(eq(ptr, csptr));
317   EXPECT_TRUE(eq(ptr, cuptr));
318   EXPECT_FALSE(eq(&dummy, cptr));
319   EXPECT_FALSE(eq(&dummy, sptr));
320   EXPECT_FALSE(eq(&dummy, uptr));
321   EXPECT_FALSE(eq(&dummy, csptr));
322   EXPECT_FALSE(eq(&dummy, cuptr));
323 }
324 
TEST(Hash,DerivedAndBase)325 TEST(Hash, DerivedAndBase) {
326   struct Base {};
327   struct Derived : Base {};
328 
329   hash_default_hash<Base*> hasher;
330 
331   Base base;
332   Derived derived;
333   EXPECT_NE(hasher(&base), hasher(&derived));
334   EXPECT_EQ(hasher(static_cast<Base*>(&derived)), hasher(&derived));
335 
336   auto dp = std::make_shared<Derived>();
337   EXPECT_EQ(hasher(static_cast<Base*>(dp.get())), hasher(dp));
338 }
339 
TEST(Hash,FunctionPointer)340 TEST(Hash, FunctionPointer) {
341   using Func = int (*)();
342   hash_default_hash<Func> hasher;
343   hash_default_eq<Func> eq;
344 
345   Func p1 = [] { return 1; }, p2 = [] { return 2; };
346   EXPECT_EQ(hasher(p1), hasher(p1));
347   EXPECT_TRUE(eq(p1, p1));
348 
349   EXPECT_NE(hasher(p1), hasher(p2));
350   EXPECT_FALSE(eq(p1, p2));
351 }
352 
TYPED_TEST(HashPointer,Works)353 TYPED_TEST(HashPointer, Works) {
354   int dummy;
355   auto hash = this->hasher;
356   auto sptr = std::make_shared<int>();
357   std::shared_ptr<const int> csptr = sptr;
358   int* ptr = sptr.get();
359   const int* cptr = ptr;
360   std::unique_ptr<int, NoDeleter> uptr(ptr);
361   std::unique_ptr<const int, NoDeleter> cuptr(ptr);
362 
363   EXPECT_EQ(hash(ptr), hash(cptr));
364   EXPECT_EQ(hash(ptr), hash(sptr));
365   EXPECT_EQ(hash(ptr), hash(uptr));
366   EXPECT_EQ(hash(ptr), hash(csptr));
367   EXPECT_EQ(hash(ptr), hash(cuptr));
368   EXPECT_NE(hash(&dummy), hash(cptr));
369   EXPECT_NE(hash(&dummy), hash(sptr));
370   EXPECT_NE(hash(&dummy), hash(uptr));
371   EXPECT_NE(hash(&dummy), hash(csptr));
372   EXPECT_NE(hash(&dummy), hash(cuptr));
373 }
374 
TEST(EqCord,Works)375 TEST(EqCord, Works) {
376   hash_default_eq<absl::Cord> eq;
377   const absl::string_view a_string_view = "a";
378   const absl::Cord a_cord(a_string_view);
379   const absl::string_view b_string_view = "b";
380   const absl::Cord b_cord(b_string_view);
381 
382   EXPECT_TRUE(eq(a_cord, a_cord));
383   EXPECT_TRUE(eq(a_cord, a_string_view));
384   EXPECT_TRUE(eq(a_string_view, a_cord));
385   EXPECT_FALSE(eq(a_cord, b_cord));
386   EXPECT_FALSE(eq(a_cord, b_string_view));
387   EXPECT_FALSE(eq(b_string_view, a_cord));
388 }
389 
TEST(HashCord,Works)390 TEST(HashCord, Works) {
391   hash_default_hash<absl::Cord> hash;
392   const absl::string_view a_string_view = "a";
393   const absl::Cord a_cord(a_string_view);
394   const absl::string_view b_string_view = "b";
395   const absl::Cord b_cord(b_string_view);
396 
397   EXPECT_EQ(hash(a_cord), hash(a_cord));
398   EXPECT_EQ(hash(b_cord), hash(b_cord));
399   EXPECT_EQ(hash(a_string_view), hash(a_cord));
400   EXPECT_EQ(hash(b_string_view), hash(b_cord));
401   EXPECT_EQ(hash(absl::Cord("")), hash(""));
402   EXPECT_EQ(hash(absl::Cord()), hash(absl::string_view()));
403 
404   EXPECT_NE(hash(a_cord), hash(b_cord));
405   EXPECT_NE(hash(a_cord), hash(b_string_view));
406   EXPECT_NE(hash(a_string_view), hash(b_cord));
407   EXPECT_NE(hash(a_string_view), hash(b_string_view));
408 }
409 
NoOpReleaser(absl::string_view data,void * arg)410 void NoOpReleaser(absl::string_view data, void* arg) {}
411 
TEST(HashCord,FragmentedCordWorks)412 TEST(HashCord, FragmentedCordWorks) {
413   hash_default_hash<absl::Cord> hash;
414   absl::Cord c = absl::MakeFragmentedCord({"a", "b", "c"});
415   EXPECT_FALSE(c.TryFlat().has_value());
416   EXPECT_EQ(hash(c), hash("abc"));
417 }
418 
TEST(HashCord,FragmentedLongCordWorks)419 TEST(HashCord, FragmentedLongCordWorks) {
420   hash_default_hash<absl::Cord> hash;
421   // Crete some large strings which do not fit on the stack.
422   std::string a(65536, 'a');
423   std::string b(65536, 'b');
424   absl::Cord c = absl::MakeFragmentedCord({a, b});
425   EXPECT_FALSE(c.TryFlat().has_value());
426   EXPECT_EQ(hash(c), hash(a + b));
427 }
428 
TEST(HashCord,RandomCord)429 TEST(HashCord, RandomCord) {
430   hash_default_hash<absl::Cord> hash;
431   auto bitgen = absl::BitGen();
432   for (int i = 0; i < 1000; ++i) {
433     const int number_of_segments = absl::Uniform(bitgen, 0, 10);
434     std::vector<std::string> pieces;
435     for (size_t s = 0; s < number_of_segments; ++s) {
436       std::string str;
437       str.resize(absl::Uniform(bitgen, 0, 4096));
438       // MSVC needed the explicit return type in the lambda.
439       std::generate(str.begin(), str.end(), [&]() -> char {
440         return static_cast<char>(absl::Uniform<unsigned char>(bitgen));
441       });
442       pieces.push_back(str);
443     }
444     absl::Cord c = absl::MakeFragmentedCord(pieces);
445     EXPECT_EQ(hash(c), hash(std::string(c)));
446   }
447 }
448 
449 // Cartesian product of (std::string, absl::string_view)
450 // with (std::string, absl::string_view, const char*, absl::Cord).
451 using StringTypesCartesianProduct = Types<
452     // clang-format off
453     std::pair<absl::Cord, std::string>,
454     std::pair<absl::Cord, absl::string_view>,
455     std::pair<absl::Cord, absl::Cord>,
456     std::pair<absl::Cord, const char*>,
457 
458     std::pair<std::string, absl::Cord>,
459     std::pair<absl::string_view, absl::Cord>,
460 
461     std::pair<absl::string_view, std::string>,
462     std::pair<absl::string_view, absl::string_view>,
463     std::pair<absl::string_view, const char*>>;
464 // clang-format on
465 
466 constexpr char kFirstString[] = "abc123";
467 constexpr char kSecondString[] = "ijk456";
468 
469 template <typename T>
470 struct StringLikeTest : public ::testing::Test {
471   typename T::first_type a1{kFirstString};
472   typename T::second_type b1{kFirstString};
473   typename T::first_type a2{kSecondString};
474   typename T::second_type b2{kSecondString};
475   hash_default_eq<typename T::first_type> eq;
476   hash_default_hash<typename T::first_type> hash;
477 };
478 
479 TYPED_TEST_SUITE_P(StringLikeTest);
480 
TYPED_TEST_P(StringLikeTest,Eq)481 TYPED_TEST_P(StringLikeTest, Eq) {
482   EXPECT_TRUE(this->eq(this->a1, this->b1));
483   EXPECT_TRUE(this->eq(this->b1, this->a1));
484 }
485 
TYPED_TEST_P(StringLikeTest,NotEq)486 TYPED_TEST_P(StringLikeTest, NotEq) {
487   EXPECT_FALSE(this->eq(this->a1, this->b2));
488   EXPECT_FALSE(this->eq(this->b2, this->a1));
489 }
490 
TYPED_TEST_P(StringLikeTest,HashEq)491 TYPED_TEST_P(StringLikeTest, HashEq) {
492   EXPECT_EQ(this->hash(this->a1), this->hash(this->b1));
493   EXPECT_EQ(this->hash(this->a2), this->hash(this->b2));
494   // It would be a poor hash function which collides on these strings.
495   EXPECT_NE(this->hash(this->a1), this->hash(this->b2));
496 }
497 
498 TYPED_TEST_SUITE(StringLikeTest, StringTypesCartesianProduct);
499 
500 }  // namespace
501 }  // namespace container_internal
502 ABSL_NAMESPACE_END
503 }  // namespace absl
504 
505 enum Hash : size_t {
506   kStd = 0x1,       // std::hash
507 #ifdef _MSC_VER
508   kExtension = kStd,  // In MSVC, std::hash == ::hash
509 #else                 // _MSC_VER
510   kExtension = 0x2,  // ::hash (GCC extension)
511 #endif                // _MSC_VER
512 };
513 
514 // H is a bitmask of Hash enumerations.
515 // Hashable<H> is hashable via all means specified in H.
516 template <int H>
517 struct Hashable {
HashableByHashable518   static constexpr bool HashableBy(Hash h) { return h & H; }
519 };
520 
521 namespace std {
522 template <int H>
523 struct hash<Hashable<H>> {
524   template <class E = Hashable<H>,
525             class = typename std::enable_if<E::HashableBy(kStd)>::type>
operator ()std::hash526   size_t operator()(E) const {
527     return kStd;
528   }
529 };
530 }  // namespace std
531 
532 namespace absl {
533 ABSL_NAMESPACE_BEGIN
534 namespace container_internal {
535 namespace {
536 
537 template <class T>
Hash(const T & v)538 size_t Hash(const T& v) {
539   return hash_default_hash<T>()(v);
540 }
541 
TEST(Delegate,HashDispatch)542 TEST(Delegate, HashDispatch) {
543   EXPECT_EQ(Hash(kStd), Hash(Hashable<kStd>()));
544 }
545 
546 }  // namespace
547 }  // namespace container_internal
548 ABSL_NAMESPACE_END
549 }  // namespace absl
550