[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / unittests / ADT / HashingTest.cpp
blobbb19a569999f2dc3cae4eaff07d4da73c13ff6fd
1 //===- llvm/unittest/ADT/HashingTest.cpp ----------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Hashing.h unit tests.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/ADT/Hashing.h"
14 #include "llvm/Support/DataTypes.h"
15 #include "llvm/Support/HashBuilder.h"
16 #include "gtest/gtest.h"
17 #include <deque>
18 #include <list>
19 #include <map>
20 #include <vector>
22 namespace llvm {
24 // Helper for test code to print hash codes.
25 void PrintTo(const hash_code &code, std::ostream *os) {
26 *os << static_cast<size_t>(code);
29 // Fake an object that is recognized as hashable data to test super large
30 // objects.
31 struct LargeTestInteger { uint64_t arr[8]; };
33 struct NonPOD {
34 uint64_t x, y;
35 NonPOD(uint64_t x, uint64_t y) : x(x), y(y) {}
36 friend hash_code hash_value(const NonPOD &obj) {
37 return hash_combine(obj.x, obj.y);
41 namespace hashing {
42 namespace detail {
43 template <> struct is_hashable_data<LargeTestInteger> : std::true_type {};
44 } // namespace detail
45 } // namespace hashing
47 } // namespace llvm
49 using namespace llvm;
51 namespace {
53 enum TestEnumeration {
54 TE_Foo = 42,
55 TE_Bar = 43
58 TEST(HashingTest, HashValueBasicTest) {
59 int x = 42, y = 43, c = 'x';
60 void *p = nullptr;
61 uint64_t i = 71;
62 const unsigned ci = 71;
63 volatile int vi = 71;
64 const volatile int cvi = 71;
65 uintptr_t addr = reinterpret_cast<uintptr_t>(&y);
66 EXPECT_EQ(hash_value(42), hash_value(x));
67 EXPECT_EQ(hash_value(42), hash_value(TE_Foo));
68 EXPECT_NE(hash_value(42), hash_value(y));
69 EXPECT_NE(hash_value(42), hash_value(TE_Bar));
70 EXPECT_NE(hash_value(42), hash_value(p));
71 EXPECT_EQ(hash_value(71), hash_value(i));
72 EXPECT_EQ(hash_value(71), hash_value(ci));
73 EXPECT_EQ(hash_value(71), hash_value(vi));
74 EXPECT_EQ(hash_value(71), hash_value(cvi));
75 EXPECT_EQ(hash_value(c), hash_value('x'));
76 EXPECT_EQ(hash_value('4'), hash_value('0' + 4));
77 EXPECT_EQ(hash_value(addr), hash_value(&y));
80 TEST(HashingTest, HashValueStdPair) {
81 EXPECT_EQ(hash_combine(42, 43), hash_value(std::make_pair(42, 43)));
82 EXPECT_NE(hash_combine(43, 42), hash_value(std::make_pair(42, 43)));
83 EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42ull, 43ull)));
84 EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42, 43ull)));
85 EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42ull, 43)));
87 // Note that pairs are implicitly flattened to a direct sequence of data and
88 // hashed efficiently as a consequence.
89 EXPECT_EQ(hash_combine(42, 43, 44),
90 hash_value(std::make_pair(42, std::make_pair(43, 44))));
91 EXPECT_EQ(hash_value(std::make_pair(42, std::make_pair(43, 44))),
92 hash_value(std::make_pair(std::make_pair(42, 43), 44)));
94 // Ensure that pairs which have padding bytes *inside* them don't get treated
95 // this way.
96 EXPECT_EQ(hash_combine('0', hash_combine(1ull, '2')),
97 hash_value(std::make_pair('0', std::make_pair(1ull, '2'))));
99 // Ensure that non-POD pairs don't explode the traits used.
100 NonPOD obj1(1, 2), obj2(3, 4), obj3(5, 6);
101 EXPECT_EQ(hash_combine(obj1, hash_combine(obj2, obj3)),
102 hash_value(std::make_pair(obj1, std::make_pair(obj2, obj3))));
105 TEST(HashingTest, HashValueStdTuple) {
106 EXPECT_EQ(hash_combine(), hash_value(std::make_tuple()));
107 EXPECT_EQ(hash_combine(42), hash_value(std::make_tuple(42)));
108 EXPECT_EQ(hash_combine(42, 'c'), hash_value(std::make_tuple(42, 'c')));
110 EXPECT_NE(hash_combine(43, 42), hash_value(std::make_tuple(42, 43)));
111 EXPECT_NE(hash_combine(42, 43), hash_value(std::make_tuple(42ull, 43ull)));
112 EXPECT_NE(hash_combine(42, 43), hash_value(std::make_tuple(42, 43ull)));
113 EXPECT_NE(hash_combine(42, 43), hash_value(std::make_tuple(42ull, 43)));
116 TEST(HashingTest, HashValueStdString) {
117 std::string s = "Hello World!";
118 EXPECT_EQ(hash_combine_range(s.c_str(), s.c_str() + s.size()), hash_value(s));
119 EXPECT_EQ(hash_combine_range(s.c_str(), s.c_str() + s.size() - 1),
120 hash_value(s.substr(0, s.size() - 1)));
121 EXPECT_EQ(hash_combine_range(s.c_str() + 1, s.c_str() + s.size() - 1),
122 hash_value(s.substr(1, s.size() - 2)));
124 std::wstring ws = L"Hello Wide World!";
125 EXPECT_EQ(hash_combine_range(ws.c_str(), ws.c_str() + ws.size()),
126 hash_value(ws));
127 EXPECT_EQ(hash_combine_range(ws.c_str(), ws.c_str() + ws.size() - 1),
128 hash_value(ws.substr(0, ws.size() - 1)));
129 EXPECT_EQ(hash_combine_range(ws.c_str() + 1, ws.c_str() + ws.size() - 1),
130 hash_value(ws.substr(1, ws.size() - 2)));
133 template <typename T, size_t N> T *begin(T (&arr)[N]) { return arr; }
134 template <typename T, size_t N> T *end(T (&arr)[N]) { return arr + N; }
136 // Provide a dummy, hashable type designed for easy verification: its hash is
137 // the same as its value.
138 struct HashableDummy { size_t value; };
139 hash_code hash_value(HashableDummy dummy) { return dummy.value; }
141 TEST(HashingTest, HashCombineRangeBasicTest) {
142 // Leave this uninitialized in the hope that valgrind will catch bad reads.
143 int dummy;
144 hash_code dummy_hash = hash_combine_range(&dummy, &dummy);
145 EXPECT_NE(hash_code(0), dummy_hash);
147 const int arr1[] = { 1, 2, 3 };
148 hash_code arr1_hash = hash_combine_range(begin(arr1), end(arr1));
149 EXPECT_NE(dummy_hash, arr1_hash);
150 EXPECT_EQ(arr1_hash, hash_combine_range(begin(arr1), end(arr1)));
152 const std::vector<int> vec(begin(arr1), end(arr1));
153 EXPECT_EQ(arr1_hash, hash_combine_range(vec.begin(), vec.end()));
155 const std::list<int> list(begin(arr1), end(arr1));
156 EXPECT_EQ(arr1_hash, hash_combine_range(list.begin(), list.end()));
158 const std::deque<int> deque(begin(arr1), end(arr1));
159 EXPECT_EQ(arr1_hash, hash_combine_range(deque.begin(), deque.end()));
161 const int arr2[] = { 3, 2, 1 };
162 hash_code arr2_hash = hash_combine_range(begin(arr2), end(arr2));
163 EXPECT_NE(dummy_hash, arr2_hash);
164 EXPECT_NE(arr1_hash, arr2_hash);
166 const int arr3[] = { 1, 1, 2, 3 };
167 hash_code arr3_hash = hash_combine_range(begin(arr3), end(arr3));
168 EXPECT_NE(dummy_hash, arr3_hash);
169 EXPECT_NE(arr1_hash, arr3_hash);
171 const int arr4[] = { 1, 2, 3, 3 };
172 hash_code arr4_hash = hash_combine_range(begin(arr4), end(arr4));
173 EXPECT_NE(dummy_hash, arr4_hash);
174 EXPECT_NE(arr1_hash, arr4_hash);
176 const size_t arr5[] = { 1, 2, 3 };
177 const HashableDummy d_arr5[] = { {1}, {2}, {3} };
178 hash_code arr5_hash = hash_combine_range(begin(arr5), end(arr5));
179 hash_code d_arr5_hash = hash_combine_range(begin(d_arr5), end(d_arr5));
180 EXPECT_EQ(arr5_hash, d_arr5_hash);
183 TEST(HashingTest, HashCombineRangeLengthDiff) {
184 // Test that as only the length varies, we compute different hash codes for
185 // sequences.
186 std::map<size_t, size_t> code_to_size;
187 std::vector<char> all_one_c(256, '\xff');
188 for (unsigned Idx = 1, Size = all_one_c.size(); Idx < Size; ++Idx) {
189 hash_code code = hash_combine_range(&all_one_c[0], &all_one_c[0] + Idx);
190 std::map<size_t, size_t>::iterator
191 I = code_to_size.insert(std::make_pair(code, Idx)).first;
192 EXPECT_EQ(Idx, I->second);
194 code_to_size.clear();
195 std::vector<char> all_zero_c(256, '\0');
196 for (unsigned Idx = 1, Size = all_zero_c.size(); Idx < Size; ++Idx) {
197 hash_code code = hash_combine_range(&all_zero_c[0], &all_zero_c[0] + Idx);
198 std::map<size_t, size_t>::iterator
199 I = code_to_size.insert(std::make_pair(code, Idx)).first;
200 EXPECT_EQ(Idx, I->second);
202 code_to_size.clear();
203 std::vector<unsigned> all_one_int(512, -1);
204 for (unsigned Idx = 1, Size = all_one_int.size(); Idx < Size; ++Idx) {
205 hash_code code = hash_combine_range(&all_one_int[0], &all_one_int[0] + Idx);
206 std::map<size_t, size_t>::iterator
207 I = code_to_size.insert(std::make_pair(code, Idx)).first;
208 EXPECT_EQ(Idx, I->second);
210 code_to_size.clear();
211 std::vector<unsigned> all_zero_int(512, 0);
212 for (unsigned Idx = 1, Size = all_zero_int.size(); Idx < Size; ++Idx) {
213 hash_code code = hash_combine_range(&all_zero_int[0], &all_zero_int[0] + Idx);
214 std::map<size_t, size_t>::iterator
215 I = code_to_size.insert(std::make_pair(code, Idx)).first;
216 EXPECT_EQ(Idx, I->second);
220 TEST(HashingTest, HashCombineRangeGoldenTest) {
221 struct { const char *s; uint64_t hash; } golden_data[] = {
222 #if SIZE_MAX == UINT64_MAX || SIZE_MAX == UINT32_MAX
223 { "a", 0xaeb6f9d5517c61f8ULL },
224 { "ab", 0x7ab1edb96be496b4ULL },
225 { "abc", 0xe38e60bf19c71a3fULL },
226 { "abcde", 0xd24461a66de97f6eULL },
227 { "abcdefgh", 0x4ef872ec411dec9dULL },
228 { "abcdefghijklm", 0xe8a865539f4eadfeULL },
229 { "abcdefghijklmnopqrstu", 0x261cdf85faaf4e79ULL },
230 { "abcdefghijklmnopqrstuvwxyzabcdef", 0x43ba70e4198e3b2aULL },
231 { "abcdefghijklmnopqrstuvwxyzabcdef"
232 "abcdefghijklmnopqrstuvwxyzghijkl"
233 "abcdefghijklmnopqrstuvwxyzmnopqr"
234 "abcdefghijklmnopqrstuvwxyzstuvwx"
235 "abcdefghijklmnopqrstuvwxyzyzabcd", 0xdcd57fb2afdf72beULL },
236 { "a", 0xaeb6f9d5517c61f8ULL },
237 { "aa", 0xf2b3b69a9736a1ebULL },
238 { "aaa", 0xf752eb6f07b1cafeULL },
239 { "aaaaa", 0x812bd21e1236954cULL },
240 { "aaaaaaaa", 0xff07a2cff08ac587ULL },
241 { "aaaaaaaaaaaaa", 0x84ac949d54d704ecULL },
242 { "aaaaaaaaaaaaaaaaaaaaa", 0xcb2c8fb6be8f5648ULL },
243 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0xcc40ab7f164091b6ULL },
244 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
245 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
246 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
247 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
248 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0xc58e174c1e78ffe9ULL },
249 { "z", 0x1ba160d7e8f8785cULL },
250 { "zz", 0x2c5c03172f1285d7ULL },
251 { "zzz", 0x9d2c4f4b507a2ac3ULL },
252 { "zzzzz", 0x0f03b9031735693aULL },
253 { "zzzzzzzz", 0xe674147c8582c08eULL },
254 { "zzzzzzzzzzzzz", 0x3162d9fa6938db83ULL },
255 { "zzzzzzzzzzzzzzzzzzzzz", 0x37b9a549e013620cULL },
256 { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x8921470aff885016ULL },
257 { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
258 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
259 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
260 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
261 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0xf60fdcd9beb08441ULL },
262 { "a", 0xaeb6f9d5517c61f8ULL },
263 { "ab", 0x7ab1edb96be496b4ULL },
264 { "aba", 0x3edb049950884d0aULL },
265 { "ababa", 0x8f2de9e73a97714bULL },
266 { "abababab", 0xee14a29ddf0ce54cULL },
267 { "ababababababa", 0x38b3ddaada2d52b4ULL },
268 { "ababababababababababa", 0xd3665364219f2b85ULL },
269 { "abababababababababababababababab", 0xa75cd6afbf1bc972ULL },
270 { "abababababababababababababababab"
271 "abababababababababababababababab"
272 "abababababababababababababababab"
273 "abababababababababababababababab"
274 "abababababababababababababababab", 0x840192d129f7a22bULL }
275 #else
276 #error This test only supports 64-bit and 32-bit systems.
277 #endif
279 for (unsigned i = 0; i < sizeof(golden_data)/sizeof(*golden_data); ++i) {
280 StringRef str = golden_data[i].s;
281 hash_code hash = hash_combine_range(str.begin(), str.end());
282 #if 0 // Enable this to generate paste-able text for the above structure.
283 std::string member_str = "\"" + str.str() + "\",";
284 fprintf(stderr, " { %-35s 0x%016llxULL },\n",
285 member_str.c_str(), static_cast<uint64_t>(hash));
286 #endif
287 EXPECT_EQ(static_cast<size_t>(golden_data[i].hash),
288 static_cast<size_t>(hash));
292 TEST(HashingTest, HashCombineBasicTest) {
293 // Hashing a sequence of homogenous types matches range hashing.
294 const int i1 = 42, i2 = 43, i3 = 123, i4 = 999, i5 = 0, i6 = 79;
295 const int arr1[] = { i1, i2, i3, i4, i5, i6 };
296 EXPECT_EQ(hash_combine_range(arr1, arr1 + 1), hash_combine(i1));
297 EXPECT_EQ(hash_combine_range(arr1, arr1 + 2), hash_combine(i1, i2));
298 EXPECT_EQ(hash_combine_range(arr1, arr1 + 3), hash_combine(i1, i2, i3));
299 EXPECT_EQ(hash_combine_range(arr1, arr1 + 4), hash_combine(i1, i2, i3, i4));
300 EXPECT_EQ(hash_combine_range(arr1, arr1 + 5),
301 hash_combine(i1, i2, i3, i4, i5));
302 EXPECT_EQ(hash_combine_range(arr1, arr1 + 6),
303 hash_combine(i1, i2, i3, i4, i5, i6));
305 // Hashing a sequence of heterogeneous types which *happen* to all produce the
306 // same data for hashing produces the same as a range-based hash of the
307 // fundamental values.
308 const size_t s1 = 1024, s2 = 8888, s3 = 9000000;
309 const HashableDummy d1 = { 1024 }, d2 = { 8888 }, d3 = { 9000000 };
310 const size_t arr2[] = { s1, s2, s3 };
311 EXPECT_EQ(hash_combine_range(begin(arr2), end(arr2)),
312 hash_combine(s1, s2, s3));
313 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(s1, s2, d3));
314 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(s1, d2, s3));
315 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, s2, s3));
316 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, d2, s3));
317 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, d2, d3));
319 // Permuting values causes hashes to change.
320 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i1, i1, i2));
321 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i1, i2, i1));
322 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i1, i1));
323 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i2, i1));
324 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i2, i2));
325 EXPECT_NE(hash_combine(i2, i1, i1), hash_combine(i1, i1, i2));
326 EXPECT_NE(hash_combine(i1, i1, i2), hash_combine(i1, i2, i1));
327 EXPECT_NE(hash_combine(i1, i2, i1), hash_combine(i2, i1, i1));
329 // Changing type w/o changing value causes hashes to change.
330 EXPECT_NE(hash_combine(i1, i2, i3), hash_combine((char)i1, i2, i3));
331 EXPECT_NE(hash_combine(i1, i2, i3), hash_combine(i1, (char)i2, i3));
332 EXPECT_NE(hash_combine(i1, i2, i3), hash_combine(i1, i2, (char)i3));
334 // This is array of uint64, but it should have the exact same byte pattern as
335 // an array of LargeTestIntegers.
336 const uint64_t bigarr[] = {
337 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
338 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
339 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
340 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
341 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
342 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
343 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
344 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
345 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL
347 // Hash a preposterously large integer, both aligned with the buffer and
348 // misaligned.
349 const LargeTestInteger li = { {
350 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
351 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
352 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL
353 } };
354 // Rotate the storage from 'li'.
355 const LargeTestInteger l2 = { {
356 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL, 0xdeadbeafdeadbeefULL,
357 0xfefefefededededeULL, 0xafafafafededededULL, 0xffffeeeeddddccccULL,
358 0xaaaacbcbffffababULL, 0xaaaaaaaaababababULL
359 } };
360 const LargeTestInteger l3 = { {
361 0xccddeeffeeddccbbULL, 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL,
362 0xafafafafededededULL, 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
363 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL
364 } };
365 EXPECT_EQ(hash_combine_range(begin(bigarr), end(bigarr)),
366 hash_combine(li, li, li));
367 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 9),
368 hash_combine(bigarr[0], l2));
369 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 10),
370 hash_combine(bigarr[0], bigarr[1], l3));
371 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 17),
372 hash_combine(li, bigarr[0], l2));
373 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 18),
374 hash_combine(li, bigarr[0], bigarr[1], l3));
375 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 18),
376 hash_combine(bigarr[0], l2, bigarr[9], l3));
377 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 20),
378 hash_combine(bigarr[0], l2, bigarr[9], l3, bigarr[18], bigarr[19]));
381 TEST(HashingTest, HashCombineArgs18) {
382 // This tests that we can pass in up to 18 args.
383 #define CHECK_SAME(...) \
384 EXPECT_EQ(hash_combine(__VA_ARGS__), hash_combine(__VA_ARGS__))
385 CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18);
386 CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
387 CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
388 CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
389 CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
390 CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
391 CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
392 CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
393 CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
394 CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9);
395 CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8);
396 CHECK_SAME(1, 2, 3, 4, 5, 6, 7);
397 CHECK_SAME(1, 2, 3, 4, 5, 6);
398 CHECK_SAME(1, 2, 3, 4, 5);
399 CHECK_SAME(1, 2, 3, 4);
400 CHECK_SAME(1, 2, 3);
401 CHECK_SAME(1, 2);
402 CHECK_SAME(1);
403 #undef CHECK_SAME
406 struct StructWithHashBuilderSupport {
407 char C;
408 int I;
409 template <typename HasherT, llvm::support::endianness Endianness>
410 friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
411 const StructWithHashBuilderSupport &Value) {
412 HBuilder.add(Value.C, Value.I);
416 TEST(HashingTest, HashWithHashBuilder) {
417 StructWithHashBuilderSupport S{'c', 1};
418 EXPECT_NE(static_cast<size_t>(llvm::hash_value(S)), static_cast<size_t>(0));
421 struct StructWithHashBuilderAndHashValueSupport {
422 char C;
423 int I;
424 template <typename HasherT, llvm::support::endianness Endianness>
425 friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
426 const StructWithHashBuilderAndHashValueSupport &Value) {}
427 friend hash_code
428 hash_value(const StructWithHashBuilderAndHashValueSupport &Value) {
429 return 0xbeef;
433 TEST(HashingTest, HashBuilderAndHashValue) {
434 StructWithHashBuilderAndHashValueSupport S{'c', 1};
435 EXPECT_EQ(static_cast<size_t>(hash_value(S)), static_cast<size_t>(0xbeef));
438 } // namespace