From d201571cbc608cc395f68355c145574efcc18cc0 Mon Sep 17 00:00:00 2001 From: Yedidya Feldblum Date: Mon, 16 Oct 2017 19:25:47 -0700 Subject: [PATCH] Shrink integral hasher specialization implementations Summary: [Folly] Shrink integral `hasher` specialization implementations. Instead of giving them bodies, just use inheritance. Reviewed By: luciang Differential Revision: D6067757 fbshipit-source-id: f71bd36132e1b66002493474825894b03754b34f --- folly/Hash.h | 97 ++++++++++++++-------------------------------------- 1 file changed, 25 insertions(+), 72 deletions(-) diff --git a/folly/Hash.h b/folly/Hash.h index 6d277c16..1151dc43 100644 --- a/folly/Hash.h +++ b/folly/Hash.h @@ -371,18 +371,20 @@ inline uint32_t hsieh_hash32_str(const std::string& str) { } // namespace hash namespace detail { -template -size_t integral_hash(I const& i) { - static_assert(sizeof(I) <= 8, "input type is too wide"); - if (sizeof(I) <= 4) { // the branch taken is known at compile time - auto const i32 = static_cast(i); // as impl accident, sign-extends - auto const u32 = static_cast(i32); - return static_cast(hash::jenkins_rev_mix32(u32)); - } else { - auto const u64 = static_cast(i); - return static_cast(hash::twang_mix64(u64)); +struct integral_hasher { + template + size_t operator()(I const& i) const { + static_assert(sizeof(I) <= 8, "input type is too wide"); + if (sizeof(I) <= 4) { // the branch taken is known at compile time + auto const i32 = static_cast(i); // impl accident: sign-extends + auto const u32 = static_cast(i32); + return static_cast(hash::jenkins_rev_mix32(u32)); + } else { + auto const u64 = static_cast(i); + return static_cast(hash::twang_mix64(u64)); + } } -} +}; } // namespace detail template @@ -409,86 +411,37 @@ struct hasher { }; template <> -struct hasher { - size_t operator()(unsigned long long key) const { - return detail::integral_hash(key); - } -}; +struct hasher : detail::integral_hasher {}; template <> -struct hasher { - size_t operator()(signed long long key) const { - return detail::integral_hash(key); - } -}; +struct hasher : detail::integral_hasher {}; template <> -struct hasher { - size_t operator()(unsigned long key) const { - return detail::integral_hash(key); - } -}; +struct hasher : detail::integral_hasher {}; template <> -struct hasher { - size_t operator()(signed long key) const { - return detail::integral_hash(key); - } -}; +struct hasher : detail::integral_hasher {}; template <> -struct hasher { - size_t operator()(unsigned int key) const { - return detail::integral_hash(key); - } -}; +struct hasher : detail::integral_hasher {}; template <> -struct hasher { - size_t operator()(signed int key) const { - return detail::integral_hash(key); - } -}; +struct hasher : detail::integral_hasher {}; template <> -struct hasher { - size_t operator()(unsigned short key) const { - return detail::integral_hash(key); - } -}; +struct hasher : detail::integral_hasher {}; template <> -struct hasher { - size_t operator()(signed short key) const { - return detail::integral_hash(key); - } -}; +struct hasher : detail::integral_hasher {}; template <> -struct hasher { - size_t operator()(unsigned char key) const { - return detail::integral_hash(key); - } -}; +struct hasher : detail::integral_hasher {}; template <> -struct hasher { - size_t operator()(signed char key) const { - return detail::integral_hash(key); - } -}; +struct hasher : detail::integral_hasher {}; -// char is different type from both signed char and unsigned char. -template <> -struct hasher { - using explicit_type = std::conditional< - std::is_signed::value, - signed char, - unsigned char>::type; - size_t operator()(char key) const { - return detail::integral_hash(explicit_type(key)); - } -}; +template <> // char is a different type from both signed char and unsigned char +struct hasher : detail::integral_hasher {}; template <> struct hasher { size_t operator()(const std::string& key) const { -- 2.34.1