HashingTest.cpp 20 KB

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