From 68312e19d87edc8bdcd49304a497aa75660e029a Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Mon, 9 Feb 2015 23:21:05 +0000 Subject: [PATCH] ADT: Allow up to 18 arguments in hash_combine() I just realized that the specialized metadata node patch I'm about to commit won't compile on old compilers. Bump `hash_combine()`'s support for non-variadic templates to 18 (I tested this by reversing the logic in the #ifdef). llvm-svn: 228629 --- llvm/include/llvm/ADT/Hashing.h | 309 +++++++++++++++++++++++++++++ llvm/unittests/ADT/HashingTest.cpp | 25 +++ 2 files changed, 334 insertions(+) diff --git a/llvm/include/llvm/ADT/Hashing.h b/llvm/include/llvm/ADT/Hashing.h index abf02b8cc9d5..1a51f4cf72d5 100644 --- a/llvm/include/llvm/ADT/Hashing.h +++ b/llvm/include/llvm/ADT/Hashing.h @@ -572,6 +572,171 @@ public: // Manually expanded recursive combining methods. See variadic above for // documentation. + template + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12, + const T13 &arg13, const T14 &arg14, const T15 &arg15, + const T16 &arg16, const T17 &arg17, const T18 &arg18) { + buffer_ptr = + combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6, + arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, + arg16, arg17, arg18); + } + template + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12, + const T13 &arg13, const T14 &arg14, const T15 &arg15, + const T16 &arg16, const T17 &arg17) { + buffer_ptr = + combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6, + arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, + arg16, arg17); + } + template + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12, + const T13 &arg13, const T14 &arg14, const T15 &arg15, + const T16 &arg16) { + buffer_ptr = + combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6, + arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, + arg16); + } + template + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12, + const T13 &arg13, const T14 &arg14, const T15 &arg15) { + buffer_ptr = + combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6, + arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + } + template + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12, + const T13 &arg13, const T14 &arg14) { + buffer_ptr = + combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6, + arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + } + template + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12, + const T13 &arg13) { + buffer_ptr = + combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6, + arg7, arg8, arg9, arg10, arg11, arg12, arg13); + } + template + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12) { + buffer_ptr = + combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6, + arg7, arg8, arg9, arg10, arg11, arg12); + } + template + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11) { + buffer_ptr = + combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6, + arg7, arg8, arg9, arg10, arg11); + } + template + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10) { + buffer_ptr = + combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6, + arg7, arg8, arg9, arg10); + } + template + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9) { + buffer_ptr = + combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6, + arg7, arg8, arg9); + } + template + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8) { + buffer_ptr = + combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6, + arg7, arg8); + } + template + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7) { + buffer_ptr = + combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6, + arg7); + } template hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, @@ -668,6 +833,150 @@ template hash_code hash_combine(const Ts &...args) { // What follows are manually exploded overloads for each argument width. See // the above variadic definition for documentation and specification. +template +hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12, + const T13 &arg13, const T14 &arg14, const T15 &arg15, + const T16 &arg16, const T17 &arg17, const T18 &arg18) { + ::llvm::hashing::detail::hash_combine_recursive_helper helper; + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3, + arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, + arg13, arg14, arg15, arg16, arg17, arg18); +} +template +hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12, + const T13 &arg13, const T14 &arg14, const T15 &arg15, + const T16 &arg16, const T17 &arg17) { + ::llvm::hashing::detail::hash_combine_recursive_helper helper; + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3, + arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, + arg13, arg14, arg15, arg16, arg17); +} +template +hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12, + const T13 &arg13, const T14 &arg14, const T15 &arg15, + const T16 &arg16) { + ::llvm::hashing::detail::hash_combine_recursive_helper helper; + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3, + arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, + arg13, arg14, arg15, arg16); +} +template +hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12, + const T13 &arg13, const T14 &arg14, const T15 &arg15) { + ::llvm::hashing::detail::hash_combine_recursive_helper helper; + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3, + arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, + arg13, arg14, arg15); +} +template +hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12, + const T13 &arg13, const T14 &arg14) { + ::llvm::hashing::detail::hash_combine_recursive_helper helper; + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3, + arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, + arg13, arg14); +} +template +hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12, + const T13 &arg13) { + ::llvm::hashing::detail::hash_combine_recursive_helper helper; + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3, + arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, + arg13); +} +template +hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11, const T12 &arg12) { + ::llvm::hashing::detail::hash_combine_recursive_helper helper; + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3, + arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, + arg12); +} +template +hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10, const T11 &arg11) { + ::llvm::hashing::detail::hash_combine_recursive_helper helper; + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3, + arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); +} +template +hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9, + const T10 &arg10) { + ::llvm::hashing::detail::hash_combine_recursive_helper helper; + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3, + arg4, arg5, arg6, arg7, arg8, arg9, arg10); +} +template +hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8, const T9 &arg9) { + ::llvm::hashing::detail::hash_combine_recursive_helper helper; + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3, + arg4, arg5, arg6, arg7, arg8, arg9); +} +template +hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7, const T8 &arg8) { + ::llvm::hashing::detail::hash_combine_recursive_helper helper; + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3, + arg4, arg5, arg6, arg7, arg8); +} +template +hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + const T4 &arg4, const T5 &arg5, const T6 &arg6, + const T7 &arg7) { + ::llvm::hashing::detail::hash_combine_recursive_helper helper; + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3, + arg4, arg5, arg6, arg7); +} template hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, diff --git a/llvm/unittests/ADT/HashingTest.cpp b/llvm/unittests/ADT/HashingTest.cpp index acaa83cddddd..34eb5a52eb8a 100644 --- a/llvm/unittests/ADT/HashingTest.cpp +++ b/llvm/unittests/ADT/HashingTest.cpp @@ -421,4 +421,29 @@ TEST(HashingTest, HashCombineBasicTest) { hash_combine(bigarr[0], l2, bigarr[9], l3, bigarr[18], bigarr[19])); } +TEST(HashingTest, HashCombineArgs18) { + // This tests that we can pass in up to 18 args. +#define CHECK_SAME(...) \ + EXPECT_EQ(hash_combine(__VA_ARGS__), hash_combine(__VA_ARGS__)) + CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18); + CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17); + CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14); + CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13); + CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); + CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); + CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9); + CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8); + CHECK_SAME(1, 2, 3, 4, 5, 6, 7); + CHECK_SAME(1, 2, 3, 4, 5, 6); + CHECK_SAME(1, 2, 3, 4, 5); + CHECK_SAME(1, 2, 3, 4); + CHECK_SAME(1, 2, 3); + CHECK_SAME(1, 2); + CHECK_SAME(1); +#undef CHECK_SAME +} + }