diff --git a/beast/hash/endian.h b/beast/hash/endian.h new file mode 100644 index 000000000..fe15249e0 --- /dev/null +++ b/beast/hash/endian.h @@ -0,0 +1,52 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2014, Howard Hinnant , + Vinnie Falco (key); diff --git a/beast/hash/hash_append.h b/beast/hash/hash_append.h index fb9b32881..2d8ddbe24 100644 --- a/beast/hash/hash_append.h +++ b/beast/hash/hash_append.h @@ -21,56 +21,138 @@ #ifndef BEAST_HASH_HASH_APPEND_H_INCLUDED #define BEAST_HASH_HASH_APPEND_H_INCLUDED +#include // for constexpr +#include #include #include -#if BEAST_USE_BOOST_FEATURES -#include -#endif #include #include +#include #include +#include #include +#include #include +#include #include +#include +#include #include // #include // #include -// Set to 1 to disable variadic hash_append for tuple. When set, overloads -// will be manually provided for tuples up to 10-arity. This also causes -// is_contiguously_hashable<> to always return false for tuples. -// -#ifndef BEAST_NO_TUPLE_VARIADICS -# ifdef _MSC_VER -# define BEAST_NO_TUPLE_VARIADICS 1 -# ifndef BEAST_VARIADIC_MAX -# ifdef _VARIADIC_MAX -# define BEAST_VARIADIC_MAX _VARIADIC_MAX -# else -# define BEAST_VARIADIC_MAX 10 -# endif -# endif -# else -# define BEAST_NO_TUPLE_VARIADICS 0 -# endif -#endif - -// Set to 1 if std::pair fails the trait test on a platform. -#ifndef BEAST_NO_IS_CONTIGUOUS_HASHABLE_PAIR -#define BEAST_NO_IS_CONTIGUOUS_HASHABLE_PAIR 0 -#endif - -// Set to 1 if std::tuple fails the trait test on a platform. -#ifndef BEAST_NO_IS_CONTIGUOUS_HASHABLE_TUPLE -# ifdef _MSC_VER -# define BEAST_NO_IS_CONTIGUOUS_HASHABLE_TUPLE 1 -# else -# define BEAST_NO_IS_CONTIGUOUS_HASHABLE_TUPLE 0 -# endif -#endif - namespace beast { +namespace detail { + +template +/*constexpr*/ +inline +void +reverse_bytes(T& t) +{ + unsigned char* bytes = static_cast(std::memmove(std::addressof(t), + std::addressof(t), + sizeof(T))); + for (unsigned i = 0; i < sizeof(T)/2; ++i) + std::swap(bytes[i], bytes[sizeof(T)-1-i]); +} + +template +/*constexpr*/ +inline +void +maybe_reverse_bytes(T& t, std::true_type) +{ +} + +template +/*constexpr*/ +inline +void +maybe_reverse_bytes(T& t, std::false_type) +{ + reverse_bytes(t); +} + +template +/*constexpr*/ +inline +void +maybe_reverse_bytes(T& t, Hasher&) +{ + maybe_reverse_bytes(t, std::integral_constant{}); +} + +} // detail + +// is_uniquely_represented + +// A type T is contiguously hashable if for all combinations of two values of +// a type, say x and y, if x == y, then it must also be true that +// memcmp(addressof(x), addressof(y), sizeof(T)) == 0. I.e. if x == y, +// then x and y have the same bit pattern representation. + +template +struct is_uniquely_represented + : public std::integral_constant::value || + std::is_enum::value || + std::is_pointer::value> +{}; + +template +struct is_uniquely_represented + : public is_uniquely_represented +{}; + +template +struct is_uniquely_represented + : public is_uniquely_represented +{}; + +template +struct is_uniquely_represented + : public is_uniquely_represented +{}; + +// is_uniquely_represented> + +template +struct is_uniquely_represented> + : public std::integral_constant::value && + is_uniquely_represented::value && + sizeof(T) + sizeof(U) == sizeof(std::pair)> +{ +}; + +// is_uniquely_represented> + +template +struct is_uniquely_represented> + : public std::integral_constant::value...>::value && + static_sum::value == sizeof(std::tuple)> +{ +}; + +// is_uniquely_represented + +template +struct is_uniquely_represented + : public std::integral_constant::value> +{ +}; + +// is_uniquely_represented> + +template +struct is_uniquely_represented> + : public std::integral_constant::value && + sizeof(T)*N == sizeof(std::array)> +{ +}; + /** Metafunction returning `true` if the type can be hashed in one call. For `is_contiguously_hashable::value` to be true, then for every @@ -85,61 +167,19 @@ namespace beast { though they compare equal. */ /** @{ */ -// scalars -template +template struct is_contiguously_hashable - : public std::integral_constant ::value || - std::is_enum::value || - std::is_pointer::value> -{ -}; - -// If this fails, something is wrong with the trait -static_assert (is_contiguously_hashable::value, ""); - -// pair -template -struct is_contiguously_hashable > - : public std::integral_constant ::value && - is_contiguously_hashable::value && - sizeof(T) + sizeof(U) == sizeof(std::pair)> -{ -}; - -#if ! BEAST_NO_IS_CONTIGUOUS_HASHABLE_PAIR -static_assert (is_contiguously_hashable >::value, ""); -#endif - -#if ! BEAST_NO_TUPLE_VARIADICS -// std::tuple -template -struct is_contiguously_hashable > - : public std::integral_constant ::value...>::value && - static_sum ::value == sizeof(std::tuple)> -{ -}; -#endif - -// std::array -template -struct is_contiguously_hashable > - : public std::integral_constant ::value && - sizeof(T)*N == sizeof(std::array)> -{ -}; - -static_assert (is_contiguously_hashable >::value, ""); - -#if ! BEAST_NO_IS_CONTIGUOUS_HASHABLE_TUPLE -static_assert (is_contiguously_hashable < - std::tuple >::value, ""); -#endif + : public std::integral_constant::value && + (sizeof(T) == 1 || + HashAlgorithm::endian == endian::native)> +{}; +template +struct is_contiguously_hashable + : public std::integral_constant::value && + (sizeof(T) == 1 || + HashAlgorithm::endian == endian::native)> +{}; /** @} */ //------------------------------------------------------------------------------ @@ -173,452 +213,254 @@ static_assert (is_contiguously_hashable < template inline -typename std::enable_if +std::enable_if_t < - is_contiguously_hashable::value ->::type -hash_append (Hasher& h, T const& t) noexcept + is_contiguously_hashable::value +> +hash_append(Hasher& h, T const& t) noexcept { - h.append (&t, sizeof(t)); + h(std::addressof(t), sizeof(t)); } template inline -typename std::enable_if +std::enable_if_t +< + !is_contiguously_hashable::value && + (std::is_integral::value || std::is_pointer::value || std::is_enum::value) +> +hash_append(Hasher& h, T t) noexcept +{ + detail::reverse_bytes(t); + h(std::addressof(t), sizeof(t)); +} + +template +inline +std::enable_if_t < std::is_floating_point::value ->::type -hash_append (Hasher& h, T t) noexcept +> +hash_append(Hasher& h, T t) noexcept { - // hash both signed zeroes identically if (t == 0) t = 0; - h.append (&t, sizeof(t)); + detail::maybe_reverse_bytes(t, h); + h(&t, sizeof(t)); } -// arrays - -template -inline -typename std::enable_if -< - !is_contiguously_hashable::value ->::type -hash_append (Hasher& h, T (&a)[N]) noexcept -{ - for (auto const& t : a) - hash_append (h, t); -} - -template -inline -typename std::enable_if -< - is_contiguously_hashable::value ->::type -hash_append (Hasher& h, T (&a)[N]) noexcept -{ - h.append (a, N*sizeof(T)); -} - -// nullptr_t - template inline void -hash_append (Hasher& h, std::nullptr_t p) noexcept +hash_append(Hasher& h, std::nullptr_t) noexcept { - h.append (&p, sizeof(p)); + void const* p = nullptr; + detail::maybe_reverse_bytes(p, h); + h(&p, sizeof(p)); } -// strings +// Forward declarations for ADL purposes + +template +std::enable_if_t +< + !is_contiguously_hashable::value +> +hash_append(Hasher& h, T (&a)[N]) noexcept; template -inline -void -hash_append (Hasher& h, - std::basic_string const& s) noexcept -{ - h.append (s.data (), (s.size()+1)*sizeof(CharT)); -} +std::enable_if_t +< + !is_contiguously_hashable::value +> +hash_append(Hasher& h, std::basic_string const& s) noexcept; -//------------------------------------------------------------------------------ - -// Forward declare hash_append for all containers. This is required so that -// argument dependent lookup works recursively (i.e. containers of containers). +template +std::enable_if_t +< + is_contiguously_hashable::value +> +hash_append(Hasher& h, std::basic_string const& s) noexcept; template -typename std::enable_if +std::enable_if_t < - !is_contiguously_hashable>::value ->::type + !is_contiguously_hashable, Hasher>::value +> hash_append (Hasher& h, std::pair const& p) noexcept; template -typename std::enable_if +std::enable_if_t < - !is_contiguously_hashable::value ->::type -hash_append (Hasher& h, std::vector const& v) noexcept; + !is_contiguously_hashable::value +> +hash_append(Hasher& h, std::vector const& v) noexcept; template -typename std::enable_if +std::enable_if_t < - is_contiguously_hashable::value ->::type -hash_append (Hasher& h, std::vector const& v) noexcept; + is_contiguously_hashable::value +> +hash_append(Hasher& h, std::vector const& v) noexcept; template -typename std::enable_if +std::enable_if_t < - !is_contiguously_hashable>::value ->::type -hash_append (Hasher& h, std::array const& a) noexcept; - -// std::tuple - -template -inline -void -hash_append (Hasher& h, std::tuple<> const& t) noexcept; - -#if BEAST_NO_TUPLE_VARIADICS - -#if BEAST_VARIADIC_MAX >= 1 -template -inline -void -hash_append (Hasher& h, std::tuple const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 2 -template -inline -void -hash_append (Hasher& h, std::tuple const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 3 -template -inline -void -hash_append (Hasher& h, std::tuple const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 4 -template -inline -void -hash_append (Hasher& h, std::tuple const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 5 -template -inline -void -hash_append (Hasher& h, std::tuple const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 6 -template -inline -void -hash_append (Hasher& h, std::tuple < - T1, T2, T3, T4, T5, T6> const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 7 -template -inline -void -hash_append (Hasher& h, std::tuple < - T1, T2, T3, T4, T5, T6, T7> const& t) noexcept; -#endif - -#if BEAST_VARIADIC_MAX >= 8 -template -inline -void -hash_append (Hasher& h, std::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, std::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, std::tuple < - T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> const& t) noexcept; -#endif - -#endif // BEAST_NO_TUPLE_VARIADICS - -//------------------------------------------------------------------------------ - -namespace detail { - -template -inline -int -hash_one (Hasher& h, T const& t) noexcept -{ - hash_append (h, t); - return 0; -} - -} // detail - -//------------------------------------------------------------------------------ - -// std::tuple - -template -inline -void -hash_append (Hasher& h, std::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, std::tuple const& t) noexcept -{ - hash_append (h, std::get<0>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 2 -template -inline -void -hash_append (Hasher& h, std::tuple const& t) noexcept -{ - hash_append (h, std::get<0>(t)); - hash_append (h, std::get<1>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 3 -template -inline -void -hash_append (Hasher& h, std::tuple const& t) noexcept -{ - hash_append (h, std::get<0>(t)); - hash_append (h, std::get<1>(t)); - hash_append (h, std::get<2>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 4 -template -inline -void -hash_append (Hasher& h, std::tuple const& t) noexcept -{ - hash_append (h, std::get<0>(t)); - hash_append (h, std::get<1>(t)); - hash_append (h, std::get<2>(t)); - hash_append (h, std::get<3>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 5 -template -inline -void -hash_append (Hasher& h, std::tuple < - T1, T2, T3, T4, T5> const& t) noexcept -{ - hash_append (h, std::get<0>(t)); - hash_append (h, std::get<1>(t)); - hash_append (h, std::get<2>(t)); - hash_append (h, std::get<3>(t)); - hash_append (h, std::get<4>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 6 -template -inline -void -hash_append (Hasher& h, std::tuple < - T1, T2, T3, T4, T5, T6> const& t) noexcept -{ - hash_append (h, std::get<0>(t)); - hash_append (h, std::get<1>(t)); - hash_append (h, std::get<2>(t)); - hash_append (h, std::get<3>(t)); - hash_append (h, std::get<4>(t)); - hash_append (h, std::get<5>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 7 -template -inline -void -hash_append (Hasher& h, std::tuple < - T1, T2, T3, T4, T5, T6, T7> const& t) noexcept -{ - hash_append (h, std::get<0>(t)); - hash_append (h, std::get<1>(t)); - hash_append (h, std::get<2>(t)); - hash_append (h, std::get<3>(t)); - hash_append (h, std::get<4>(t)); - hash_append (h, std::get<5>(t)); - hash_append (h, std::get<6>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 8 -template -inline -void -hash_append (Hasher& h, std::tuple < - T1, T2, T3, T4, T5, T6, T7, T8> const& t) noexcept -{ - hash_append (h, std::get<0>(t)); - hash_append (h, std::get<1>(t)); - hash_append (h, std::get<2>(t)); - hash_append (h, std::get<3>(t)); - hash_append (h, std::get<4>(t)); - hash_append (h, std::get<5>(t)); - hash_append (h, std::get<6>(t)); - hash_append (h, std::get<7>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 9 -template -inline -void -hash_append (Hasher& h, std::tuple < - T1, T2, T3, T4, T5, T6, T7, T8, T9> const& t) noexcept -{ - hash_append (h, std::get<0>(t)); - hash_append (h, std::get<1>(t)); - hash_append (h, std::get<2>(t)); - hash_append (h, std::get<3>(t)); - hash_append (h, std::get<4>(t)); - hash_append (h, std::get<5>(t)); - hash_append (h, std::get<6>(t)); - hash_append (h, std::get<7>(t)); - hash_append (h, std::get<8>(t)); -} -#endif - -#if BEAST_VARIADIC_MAX >= 10 -template -inline -void -hash_append (Hasher& h, std::tuple < - T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> const& t) noexcept -{ - hash_append (h, std::get<0>(t)); - hash_append (h, std::get<1>(t)); - hash_append (h, std::get<2>(t)); - hash_append (h, std::get<3>(t)); - hash_append (h, std::get<4>(t)); - hash_append (h, std::get<5>(t)); - hash_append (h, std::get<6>(t)); - hash_append (h, std::get<7>(t)); - hash_append (h, std::get<8>(t)); - hash_append (h, std::get<9>(t)); -} -#endif - -#else // BEAST_NO_TUPLE_VARIADICS - -namespace detail { - -template -inline -void -tuple_hash (Hasher& h, std::tuple const& t, - std::index_sequence) noexcept -{ - struct for_each_item { - for_each_item (...) { } - }; - for_each_item (hash_one(h, std::get(t))...); -} - -} // detail + !is_contiguously_hashable, Hasher>::value +> +hash_append(Hasher& h, std::array const& a) noexcept; template -inline -typename std::enable_if +std::enable_if_t < - !is_contiguously_hashable>::value ->::type -hash_append (Hasher& h, std::tuple const& t) noexcept + !is_contiguously_hashable, Hasher>::value +> +hash_append(Hasher& h, std::tuple const& t) noexcept; + +template +void +hash_append(Hasher& h, std::unordered_map const& m); + +template +void +hash_append(Hasher& h, std::unordered_set const& s); + +template +void +hash_append (Hasher& h, T0 const& t0, T1 const& t1, T const& ...t) noexcept; + +// c-array + +template +std::enable_if_t +< + !is_contiguously_hashable::value +> +hash_append(Hasher& h, T (&a)[N]) noexcept { - detail::tuple_hash(h, t, std::index_sequence_for{}); + for (auto const& t : a) + hash_append(h, t); } -#endif // BEAST_NO_TUPLE_VARIADICS +// basic_string + +template +inline +std::enable_if_t +< + !is_contiguously_hashable::value +> +hash_append(Hasher& h, std::basic_string const& s) noexcept +{ + for (auto c : s) + hash_append(h, c); + hash_append(h, s.size()); +} + +template +inline +std::enable_if_t +< + is_contiguously_hashable::value +> +hash_append(Hasher& h, std::basic_string const& s) noexcept +{ + h(s.data(), s.size()*sizeof(CharT)); + hash_append(h, s.size()); +} // pair template inline -typename std::enable_if +std::enable_if_t < - !is_contiguously_hashable>::value ->::type + !is_contiguously_hashable, Hasher>::value +> hash_append (Hasher& h, std::pair const& p) noexcept { - hash_append (h, p.first); - hash_append (h, p.second); + hash_append (h, p.first, p.second); } // vector template inline -typename std::enable_if +std::enable_if_t < - !is_contiguously_hashable::value ->::type -hash_append (Hasher& h, std::vector const& v) noexcept + !is_contiguously_hashable::value +> +hash_append(Hasher& h, std::vector const& v) noexcept { for (auto const& t : v) - hash_append (h, t); + hash_append(h, t); + hash_append(h, v.size()); } template inline -typename std::enable_if +std::enable_if_t < - is_contiguously_hashable::value ->::type -hash_append (Hasher& h, std::vector const& v) noexcept + is_contiguously_hashable::value +> +hash_append(Hasher& h, std::vector const& v) noexcept { - h.append (v.data(), v.size()*sizeof(T)); + h(v.data(), v.size()*sizeof(T)); + hash_append(h, v.size()); +} + +// array + +template +std::enable_if_t +< + !is_contiguously_hashable, Hasher>::value +> +hash_append(Hasher& h, std::array const& a) noexcept +{ + for (auto const& t : a) + hash_append(h, t); +} + +// tuple + +namespace detail +{ + +inline +void +for_each_item(...) noexcept +{ +} + +template +inline +int +hash_one(Hasher& h, T const& t) noexcept +{ + hash_append(h, t); + return 0; +} + +template +inline +void +tuple_hash(Hasher& h, std::tuple const& t, std::index_sequence) noexcept +{ + for_each_item(hash_one(h, std::get(t))...); +} + +} // detail + +template +inline +std::enable_if_t +< + !is_contiguously_hashable, Hasher>::value +> +hash_append(Hasher& h, std::tuple const& t) noexcept +{ + detail::tuple_hash(h, t, std::index_sequence_for{}); } // shared_ptr @@ -631,25 +473,25 @@ 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 +// variadic template inline void hash_append (Hasher& h, T0 const& t0, T1 const& t1, T const& ...t) noexcept { - hash_append (h, t0); - hash_append (h, t1, t...); + hash_append(h, t0); + hash_append(h, t1, t...); +} + +// error_code + +template +inline +void +hash_append(HashAlgorithm& h, std::error_code const& ec) +{ + hash_append(h, ec.value(), &ec.category()); } } // beast diff --git a/beast/hash/impl/siphash.cpp b/beast/hash/impl/siphash.cpp index 9702f5afe..174c9143c 100644 --- a/beast/hash/impl/siphash.cpp +++ b/beast/hash/impl/siphash.cpp @@ -90,7 +90,7 @@ siphash::siphash(std::uint64_t k0, std::uint64_t k1) noexcept } void -siphash::append (void const* key, std::size_t inlen) noexcept +siphash::operator() (void const* key, std::size_t inlen) noexcept { using namespace detail; u8 const* in = static_cast(key); diff --git a/beast/hash/siphash.h b/beast/hash/siphash.h index dc25a4e79..a76466231 100644 --- a/beast/hash/siphash.h +++ b/beast/hash/siphash.h @@ -48,7 +48,7 @@ public: siphash (std::uint64_t k0, std::uint64_t k1 = 0) noexcept; void - append (void const* key, std::size_t len) noexcept; + operator() (void const* key, std::size_t len) noexcept; explicit operator std::size_t() noexcept; diff --git a/beast/hash/spooky.h b/beast/hash/spooky.h index 84270d022..228517dda 100644 --- a/beast/hash/spooky.h +++ b/beast/hash/spooky.h @@ -21,6 +21,7 @@ #ifndef BEAST_HASH_SPOOKY_H_INCLUDED #define BEAST_HASH_SPOOKY_H_INCLUDED +#include #include namespace beast { @@ -33,6 +34,7 @@ private: public: using result_type = std::size_t; + static beast::endian const endian = beast::endian::native; spooky (std::size_t seed1 = 1, std::size_t seed2 = 2) noexcept { @@ -40,7 +42,7 @@ public: } void - append (void const* key, std::size_t len) noexcept + operator() (void const* key, std::size_t len) noexcept { state_.Update (key, len); } diff --git a/beast/hash/tests/hash_append_test.cpp b/beast/hash/tests/hash_append_test.cpp index 887278cc0..711435207 100644 --- a/beast/hash/tests/hash_append_test.cpp +++ b/beast/hash/tests/hash_append_test.cpp @@ -21,6 +21,7 @@ #include #endif +#include #include #include #include @@ -120,8 +121,10 @@ private: std::uint64_t state_ = 14695981039346656037u; public: + static beast::endian const endian = beast::endian::native; + void - append (void const* key, std::size_t len) noexcept + operator() (void const* key, std::size_t len) noexcept { unsigned char const* p = static_cast(key); unsigned char const* const e = p + len; @@ -143,8 +146,10 @@ private: std::uint32_t state_ = 2166136261; public: + static beast::endian const endian = beast::endian::native; + void - append (void const* key, std::size_t len) noexcept + operator() (void const* key, std::size_t len) noexcept { unsigned char const* p = static_cast(key); unsigned char const* const e = p + len; @@ -171,8 +176,10 @@ private: std::size_t state_ = 0; public: + static beast::endian const endian = beast::endian::native; + void - append (void const* key, std::size_t len) noexcept + operator() (void const* key, std::size_t len) noexcept { unsigned char const* p = static_cast (key); unsigned char const* const e = p + len; @@ -200,13 +207,15 @@ private: SpookyHash state_; public: + static beast::endian const endian = beast::endian::native; + spooky(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 + operator()(void const* key, std::size_t len) noexcept { state_.Update(key, len); } @@ -253,7 +262,7 @@ public: } void - append (void const* data, std::size_t bytes) noexcept + operator() (void const* data, std::size_t bytes) noexcept { base::operator() (data, bytes); } @@ -340,9 +349,10 @@ public: //------------------------------------------------------------------------------ -template<> -struct is_contiguously_hashable - : std::true_type +template +struct is_contiguously_hashable + : std::integral_constant, + HashAlgorithm>::value> { }; diff --git a/beast/hash/tests/hash_speed_test.cpp b/beast/hash/tests/hash_speed_test.cpp index 42367f292..c48386d87 100644 --- a/beast/hash/tests/hash_speed_test.cpp +++ b/beast/hash/tests/hash_speed_test.cpp @@ -54,7 +54,7 @@ public: { rngfill (key, g); Hasher h; - h.append(key.data(), KeySize); + h(key.data(), KeySize); volatile size_t temp = static_cast(h); (void)temp; diff --git a/beast/hash/xxhasher.h b/beast/hash/xxhasher.h index e3c5c944d..7150db73c 100644 --- a/beast/hash/xxhasher.h +++ b/beast/hash/xxhasher.h @@ -26,6 +26,7 @@ #if ! BEAST_NO_XXHASH +#include #include #include #include // @@ -42,6 +43,8 @@ private: detail::XXH64_state_t state_; public: + static beast::endian const endian = beast::endian::native; + using result_type = std::size_t; xxhasher() noexcept @@ -67,7 +70,7 @@ public: } void - append (void const* key, std::size_t len) noexcept + operator()(void const* key, std::size_t len) noexcept { detail::XXH64_update (&state_, key, len); } diff --git a/beast/net/IPAddressV4.h b/beast/net/IPAddressV4.h index bd1a6359b..f47a9776f 100644 --- a/beast/net/IPAddressV4.h +++ b/beast/net/IPAddressV4.h @@ -178,8 +178,8 @@ std::istream& operator>> (std::istream& is, AddressV4& addr); } -template <> -struct is_contiguously_hashable +template +struct is_contiguously_hashable : public std::integral_constant { }; diff --git a/beast/nudb/detail/format.h b/beast/nudb/detail/format.h index 394177e01..e68d359a5 100644 --- a/beast/nudb/detail/format.h +++ b/beast/nudb/detail/format.h @@ -152,7 +152,7 @@ hash (void const* key, std::size_t key_size, std::size_t salt) { Hasher h (salt); - h.append (key, key_size); + h (key, key_size); return make_hash(static_cast< typename Hasher::result_type>(h)); } @@ -164,7 +164,7 @@ std::size_t pepper (std::size_t salt) { Hasher h (salt); - h.append (&salt, sizeof(salt)); + h (&salt, sizeof(salt)); return static_cast(h); } diff --git a/beast/utility/tagged_integer.h b/beast/utility/tagged_integer.h index 83f00ccc5..49033167c 100644 --- a/beast/utility/tagged_integer.h +++ b/beast/utility/tagged_integer.h @@ -45,8 +45,6 @@ template class tagged_integer { private: - friend struct is_contiguously_hashable>; - static_assert (std::is_unsigned ::value, "The specified Int type must be unsigned"); @@ -235,9 +233,9 @@ public: } }; -template -struct is_contiguously_hashable> - : public is_contiguously_hashable +template +struct is_contiguously_hashable, HashAlgorithm> + : public is_contiguously_hashable { };