diff --git a/beast/container/hardened_hash.h b/beast/container/hardened_hash.h index ff1e519170..df419aafb4 100644 --- a/beast/container/hardened_hash.h +++ b/beast/container/hardened_hash.h @@ -22,14 +22,14 @@ #include "hash_append.h" -#include "impl/spookyv2.h" - #include "../utility/noexcept.h" #include #include #include #include #include "../cxx14/type_traits.h" // +#include +#include #include "../cxx14/utility.h" // // When set to 1, makes the seed per-process instead @@ -115,30 +115,6 @@ private: //------------------------------------------------------------------------------ -class spooky_wrapper -{ - SpookyHash state_; -public: - spooky_wrapper (std::size_t seed1 = 1, std::size_t seed2 = 2) noexcept - { - state_.Init (seed1, seed2); - } - - void - append (void const* key, std::size_t len) noexcept - { - state_.Update (key, len); - } - - explicit - operator std::size_t() noexcept - { - std::uint64_t h1, h2; - state_.Final (&h1, &h2); - return static_cast (h1); - } -}; - } // detail //------------------------------------------------------------------------------ diff --git a/beast/container/hash_append.h b/beast/container/hash_append.h index f4bcf3d595..1843911cfb 100644 --- a/beast/container/hash_append.h +++ b/beast/container/hash_append.h @@ -23,14 +23,17 @@ #include "../utility/meta.h" +#include "impl/spookyv2.h" + #if BEAST_USE_BOOST_FEATURES -#include +#include #endif #include "../utility/noexcept.h" #include #include #include +#include #include #include #include "../cxx14/type_traits.h" // @@ -141,20 +144,6 @@ static_assert (is_contiguously_hashable < std::tuple >::value, ""); #endif -#if BEAST_USE_BOOST_FEATURES - -#if ! BEAST_NO_TUPLE_VARIADICS -// boost::tuple -template -struct is_contiguously_hashable > - : public std::integral_constant ::value...>::value && - static_sum ::value == sizeof(boost::tuple)> -{ -}; -#endif - -#endif // BEAST_USE_BOOST_FEATURES /** @} */ //------------------------------------------------------------------------------ @@ -379,97 +368,6 @@ hash_append (Hasher& h, std::tuple < T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> const& t) noexcept; #endif -// boost::tuple - -#if BEAST_USE_BOOST_FEATURES - -template -inline -void -hash_append (Hasher& h, boost::tuple<> const& t) noexcept; - -#if BEAST_VARIADIC_MAX >= 1 -template -inline -void -hash_append (Hasher& h, boost::tuple const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 2 -template -inline -void -hash_append (Hasher& h, boost::tuple const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 3 -template -inline -void -hash_append (Hasher& h, boost::tuple const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 4 -template -inline -void -hash_append (Hasher& h, boost::tuple const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 5 -template -inline -void -hash_append (Hasher& h, boost::tuple const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 6 -template -inline -void -hash_append (Hasher& h, boost::tuple < - T1, T2, T3, T4, T5, T6> const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 7 -template -inline -void -hash_append (Hasher& h, boost::tuple < - T1, T2, T3, T4, T5, T6, T7> const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 8 -template -inline -void -hash_append (Hasher& h, boost::tuple < - T1, T2, T3, T4, T5, T6, T7, T8> const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 9 -template -inline -void -hash_append (Hasher& h, boost::tuple < - T1, T2, T3, T4, T5, T6, T7, T8, T9> const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 10 -template -inline -void -hash_append (Hasher& h, boost::tuple < - T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> const& t) noexcept; -#endif - -#endif // BEAST_USE_BOOST_FEATURES - #endif // BEAST_NO_TUPLE_VARIADICS //------------------------------------------------------------------------------ @@ -688,209 +586,6 @@ hash_append (Hasher& h, std::tuple const& t) noexcept #endif // BEAST_NO_TUPLE_VARIADICS -// boost::tuple - -#if BEAST_USE_BOOST_FEATURES - -template -inline -void -hash_append (Hasher& h, boost::tuple<> const& t) noexcept -{ - hash_append (h, nullptr); -} - -#if BEAST_NO_TUPLE_VARIADICS - -#if BEAST_VARIADIC_MAX >= 1 -template -inline -void -hash_append (Hasher& h, boost::tuple const& t) noexcept -{ - hash_append (h, boost::get<0>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 2 -template -inline -void -hash_append (Hasher& h, boost::tuple const& t) noexcept -{ - hash_append (h, boost::get<0>(t)); - hash_append (h, boost::get<1>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 3 -template -inline -void -hash_append (Hasher& h, boost::tuple const& t) noexcept -{ - hash_append (h, boost::get<0>(t)); - hash_append (h, boost::get<1>(t)); - hash_append (h, boost::get<2>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 4 -template -inline -void -hash_append (Hasher& h, boost::tuple const& t) noexcept -{ - hash_append (h, boost::get<0>(t)); - hash_append (h, boost::get<1>(t)); - hash_append (h, boost::get<2>(t)); - hash_append (h, boost::get<3>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 5 -template -inline -void -hash_append (Hasher& h, boost::tuple < - T1, T2, T3, T4, T5> const& t) noexcept -{ - hash_append (h, boost::get<0>(t)); - hash_append (h, boost::get<1>(t)); - hash_append (h, boost::get<2>(t)); - hash_append (h, boost::get<3>(t)); - hash_append (h, boost::get<4>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 6 -template -inline -void -hash_append (Hasher& h, boost::tuple < - T1, T2, T3, T4, T5, T6> const& t) noexcept -{ - hash_append (h, boost::get<0>(t)); - hash_append (h, boost::get<1>(t)); - hash_append (h, boost::get<2>(t)); - hash_append (h, boost::get<3>(t)); - hash_append (h, boost::get<4>(t)); - hash_append (h, boost::get<5>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 7 -template -inline -void -hash_append (Hasher& h, boost::tuple < - T1, T2, T3, T4, T5, T6, T7> const& t) noexcept -{ - hash_append (h, boost::get<0>(t)); - hash_append (h, boost::get<1>(t)); - hash_append (h, boost::get<2>(t)); - hash_append (h, boost::get<3>(t)); - hash_append (h, boost::get<4>(t)); - hash_append (h, boost::get<5>(t)); - hash_append (h, boost::get<6>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 8 -template -inline -void -hash_append (Hasher& h, boost::tuple < - T1, T2, T3, T4, T5, T6, T7, T8> const& t) noexcept -{ - hash_append (h, boost::get<0>(t)); - hash_append (h, boost::get<1>(t)); - hash_append (h, boost::get<2>(t)); - hash_append (h, boost::get<3>(t)); - hash_append (h, boost::get<4>(t)); - hash_append (h, boost::get<5>(t)); - hash_append (h, boost::get<6>(t)); - hash_append (h, boost::get<7>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 9 -template -inline -void -hash_append (Hasher& h, boost::tuple < - T1, T2, T3, T4, T5, T6, T7, T8, T9> const& t) noexcept -{ - hash_append (h, boost::get<0>(t)); - hash_append (h, boost::get<1>(t)); - hash_append (h, boost::get<2>(t)); - hash_append (h, boost::get<3>(t)); - hash_append (h, boost::get<4>(t)); - hash_append (h, boost::get<5>(t)); - hash_append (h, boost::get<6>(t)); - hash_append (h, boost::get<7>(t)); - hash_append (h, boost::get<8>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 10 -template -inline -void -hash_append (Hasher& h, boost::tuple < - T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> const& t) noexcept -{ - hash_append (h, boost::get<0>(t)); - hash_append (h, boost::get<1>(t)); - hash_append (h, boost::get<2>(t)); - hash_append (h, boost::get<3>(t)); - hash_append (h, boost::get<4>(t)); - hash_append (h, boost::get<5>(t)); - hash_append (h, boost::get<6>(t)); - hash_append (h, boost::get<7>(t)); - hash_append (h, boost::get<8>(t)); - hash_append (h, boost::get<9>(t)); -} -#endif - -#else // BEAST_NO_TUPLE_VARIADICS - -namespace detail { - -template -inline -void -tuple_hash (Hasher& h, boost::tuple const& t, - std::index_sequence) noexcept -{ - struct for_each_item { - for_each_item (...) { } - }; - for_each_item (hash_one(h, boost::get(t))...); -} - -} // detail - -template -inline -typename std::enable_if -< - !is_contiguously_hashable>::value ->::type -hash_append (Hasher& h, boost::tuple const& t) noexcept -{ - detail::tuple_hash(h, t, std::index_sequence_for{}); -} - -#endif // BEAST_NO_TUPLE_VARIADICS - -#endif // BEAST_USE_BOOST_FEATURES - // pair template @@ -930,6 +625,28 @@ hash_append (Hasher& h, std::vector const& v) noexcept h.append (v.data(), v.size()*sizeof(T)); } +// shared_ptr + +template +inline +void +hash_append (Hasher& h, std::shared_ptr const& p) noexcept +{ + hash_append(h, p.get()); +} + +#if BEAST_USE_BOOST_FEATURES +template +inline +void +hash_append (Hasher& h, boost::shared_ptr const& p) noexcept +{ + hash_append(h, p.get()); +} +#endif + +// variadic hash_append + template inline void @@ -939,6 +656,62 @@ hash_append (Hasher& h, T0 const& t0, T1 const& t1, T const& ...t) noexcept hash_append (h, t1, t...); } +namespace detail +{ + +class spooky_wrapper +{ + SpookyHash state_; +public: + using result_type = std::size_t; + + spooky_wrapper (std::size_t seed1 = 1, std::size_t seed2 = 2) noexcept + { + state_.Init (seed1, seed2); + } + + void + append (void const* key, std::size_t len) noexcept + { + state_.Update (key, len); + } + + explicit + operator std::size_t() noexcept + { + std::uint64_t h1, h2; + state_.Final (&h1, &h2); + return static_cast (h1); + } +}; + +} // detail + +template +struct uhash +{ + using result_type = typename Hasher::result_type; + + template + result_type + operator()(T const& t) const noexcept + { + Hasher h; + hash_append (h, t); + return static_cast(h); + } +}; + +struct call_hash_value +{ + template + std::size_t + operator()(T const& t) const noexcept + { + return hash_value(t); + } +}; + } // beast #endif diff --git a/beast/container/tests/hash_append.test.cpp b/beast/container/tests/hash_append.test.cpp index a0d0c6ca1d..c102fcd117 100644 --- a/beast/container/tests/hash_append.test.cpp +++ b/beast/container/tests/hash_append.test.cpp @@ -119,10 +119,13 @@ public: namespace hash_append_tests { -class fnv1a +template class fnv1a_imp; + +template <> +class fnv1a_imp<64> { private: - std::size_t state_ = 14695981039346656037u; + std::uint64_t state_ = 14695981039346656037u; public: void @@ -141,6 +144,35 @@ public: } }; +template <> +class fnv1a_imp<32> +{ +private: + std::uint32_t state_ = 2166136261; + +public: + void + append (void const* key, std::size_t len) noexcept + { + unsigned char const* p = static_cast(key); + unsigned char const* const e = p + len; + for (; p < e; ++p) + state_ = (state_ ^ *p) * 16777619; + } + + explicit + operator std::size_t() noexcept + { + return state_; + } +}; + +class fnv1a + : public fnv1a_imp +{ +public: +}; + class jenkins1 { private: diff --git a/beast/http/URL.h b/beast/http/URL.h index 12e2c31731..1e0e114c90 100644 --- a/beast/http/URL.h +++ b/beast/http/URL.h @@ -122,6 +122,15 @@ inline bool operator>= (URL const& lhs, URL const& rhs) { return ! (lhs.toString std::ostream& operator<< (std::ostream& os, URL const& url); /** boost::hash support */ +template +inline +void +hash_append (Hasher& h, URL const& url) +{ + using beast::hash_append; + hash_append (h, url.toString()); +} + extern std::size_t hash_value (beast::URL const& url); } diff --git a/beast/insight/impl/Groups.cpp b/beast/insight/impl/Groups.cpp index f336c56aef..a20728cc97 100644 --- a/beast/insight/impl/Groups.cpp +++ b/beast/insight/impl/Groups.cpp @@ -91,7 +91,7 @@ private: class GroupsImp : public Groups { public: - typedef std::unordered_map > Items; + typedef std::unordered_map , uhash <>> Items; Collector::ptr m_collector; Items m_items; diff --git a/beast/net/IPAddress.h b/beast/net/IPAddress.h index 1d9bb1edd1..2303c62eb9 100644 --- a/beast/net/IPAddress.h +++ b/beast/net/IPAddress.h @@ -22,6 +22,7 @@ #include "IPAddressV4.h" #include "IPAddressV6.h" +#include "../container/hash_append.h" #include #include @@ -136,6 +137,18 @@ public: return m_v6; } + template + friend + void + hash_append(Hasher& h, Address const& addr) + { + using beast::hash_append; + if (addr.is_v4 ()) + hash_append(h, addr.to_v4 ()); + else + hash_append(h, addr.to_v6 ()); + } + /** Arithmetic comparison. */ /** @{ */ friend diff --git a/beast/net/IPAddressV4.h b/beast/net/IPAddressV4.h index cf0c7bd38d..41e405fe4a 100644 --- a/beast/net/IPAddressV4.h +++ b/beast/net/IPAddressV4.h @@ -20,6 +20,8 @@ #ifndef BEAST_NET_IPADDRESSV4_H_INCLUDED #define BEAST_NET_IPADDRESSV4_H_INCLUDED +#include "../container/hash_append.h" + #include #include #include @@ -178,6 +180,13 @@ OutputStream& operator<< (OutputStream& os, AddressV4 const& addr) std::istream& operator>> (std::istream& is, AddressV4& addr); } + +template <> +struct is_contiguously_hashable + : public std::integral_constant +{ +}; + } //------------------------------------------------------------------------------ diff --git a/beast/net/IPAddressV6.h b/beast/net/IPAddressV6.h index bc3bb97d50..3d1f542cf8 100644 --- a/beast/net/IPAddressV6.h +++ b/beast/net/IPAddressV6.h @@ -71,6 +71,13 @@ bool is_public (AddressV6 const& addr); //------------------------------------------------------------------------------ +template +void +hash_append(Hasher&, AddressV6 const&) +{ + assert(false); +} + /** boost::hash support. */ inline std::size_t hash_value (AddressV6 const&) { assert(false); return 0; } diff --git a/beast/net/IPEndpoint.h b/beast/net/IPEndpoint.h index c9b64ddf4b..193881f7a3 100644 --- a/beast/net/IPEndpoint.h +++ b/beast/net/IPEndpoint.h @@ -21,6 +21,7 @@ #define BEAST_NET_IPENDPOINT_H_INCLUDED #include "IPAddress.h" +#include "../container/hash_append.h" #include #include @@ -91,6 +92,15 @@ public: { return ! (rhs > lhs); } /** @} */ + template + friend + void + hash_append (Hasher& h, Endpoint const& endpoint) + { + using beast::hash_append; + hash_append(h, endpoint.m_addr, endpoint.m_port); + } + private: Address m_addr; Port m_port; diff --git a/beast/strings/String.h b/beast/strings/String.h index db7a0df480..b49ad06e04 100644 --- a/beast/strings/String.h +++ b/beast/strings/String.h @@ -1215,6 +1215,14 @@ public: String convertToPrecomposedUnicode() const; #endif + template + friend + void + hash_append (Hasher& h, String const& s) + { + h.append(s.text.getAddress(), s.text.sizeInBytes()); + } + private: //============================================================================== struct FromNumber { };