mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Rearrange sources (#4997)
This commit is contained in:
committed by
John Freeman
parent
2e902dee53
commit
e416ee72ca
505
include/xrpl/beast/hash/hash_append.h
Normal file
505
include/xrpl/beast/hash/hash_append.h
Normal file
@@ -0,0 +1,505 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
|
||||
Vinnie Falco <vinnie.falco@gmail.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HASH_HASH_APPEND_H_INCLUDED
|
||||
#define BEAST_HASH_HASH_APPEND_H_INCLUDED
|
||||
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
/*constexpr*/
|
||||
inline void
|
||||
reverse_bytes(T& t)
|
||||
{
|
||||
unsigned char* bytes = static_cast<unsigned char*>(
|
||||
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 <class T>
|
||||
/*constexpr*/
|
||||
inline void
|
||||
maybe_reverse_bytes(T& t, std::false_type)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
/*constexpr*/
|
||||
inline void
|
||||
maybe_reverse_bytes(T& t, std::true_type)
|
||||
{
|
||||
reverse_bytes(t);
|
||||
}
|
||||
|
||||
template <class T, class Hasher>
|
||||
/*constexpr*/
|
||||
inline void
|
||||
maybe_reverse_bytes(T& t, Hasher&)
|
||||
{
|
||||
maybe_reverse_bytes(
|
||||
t,
|
||||
std::integral_constant<
|
||||
bool,
|
||||
Hasher::endian != boost::endian::order::native>{});
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// is_uniquely_represented<T>
|
||||
|
||||
// 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 <class T>
|
||||
struct is_uniquely_represented
|
||||
: public std::integral_constant<
|
||||
bool,
|
||||
std::is_integral<T>::value || std::is_enum<T>::value ||
|
||||
std::is_pointer<T>::value>
|
||||
{
|
||||
explicit is_uniquely_represented() = default;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_uniquely_represented<T const> : public is_uniquely_represented<T>
|
||||
{
|
||||
explicit is_uniquely_represented() = default;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_uniquely_represented<T volatile> : public is_uniquely_represented<T>
|
||||
{
|
||||
explicit is_uniquely_represented() = default;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_uniquely_represented<T const volatile>
|
||||
: public is_uniquely_represented<T>
|
||||
{
|
||||
explicit is_uniquely_represented() = default;
|
||||
};
|
||||
|
||||
// is_uniquely_represented<std::pair<T, U>>
|
||||
|
||||
template <class T, class U>
|
||||
struct is_uniquely_represented<std::pair<T, U>>
|
||||
: public std::integral_constant<
|
||||
bool,
|
||||
is_uniquely_represented<T>::value &&
|
||||
is_uniquely_represented<U>::value &&
|
||||
sizeof(T) + sizeof(U) == sizeof(std::pair<T, U>)>
|
||||
{
|
||||
explicit is_uniquely_represented() = default;
|
||||
};
|
||||
|
||||
// is_uniquely_represented<std::tuple<T...>>
|
||||
|
||||
template <class... T>
|
||||
struct is_uniquely_represented<std::tuple<T...>>
|
||||
: public std::integral_constant<
|
||||
bool,
|
||||
std::conjunction_v<is_uniquely_represented<T>...> &&
|
||||
sizeof(std::tuple<T...>) == (sizeof(T) + ...)>
|
||||
{
|
||||
explicit is_uniquely_represented() = default;
|
||||
};
|
||||
|
||||
// is_uniquely_represented<T[N]>
|
||||
|
||||
template <class T, std::size_t N>
|
||||
struct is_uniquely_represented<T[N]> : public is_uniquely_represented<T>
|
||||
{
|
||||
explicit is_uniquely_represented() = default;
|
||||
};
|
||||
|
||||
// is_uniquely_represented<std::array<T, N>>
|
||||
|
||||
template <class T, std::size_t N>
|
||||
struct is_uniquely_represented<std::array<T, N>>
|
||||
: public std::integral_constant<
|
||||
bool,
|
||||
is_uniquely_represented<T>::value &&
|
||||
sizeof(T) * N == sizeof(std::array<T, N>)>
|
||||
{
|
||||
explicit is_uniquely_represented() = default;
|
||||
};
|
||||
|
||||
/** Metafunction returning `true` if the type can be hashed in one call.
|
||||
|
||||
For `is_contiguously_hashable<T>::value` to be true, then for every
|
||||
combination of possible values of `T` held in `x` and `y`,
|
||||
if `x == y`, then it must be true that `memcmp(&x, &y, sizeof(T))`
|
||||
return 0; i.e. that `x` and `y` are represented by the same bit pattern.
|
||||
|
||||
For example: A two's complement `int` should be contiguously hashable.
|
||||
Every bit pattern produces a unique value that does not compare equal to
|
||||
any other bit pattern's value. A IEEE floating point should not be
|
||||
contiguously hashable because -0. and 0. have different bit patterns,
|
||||
though they compare equal.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class T, class HashAlgorithm>
|
||||
struct is_contiguously_hashable
|
||||
: public std::integral_constant<
|
||||
bool,
|
||||
is_uniquely_represented<T>::value &&
|
||||
(sizeof(T) == 1 ||
|
||||
HashAlgorithm::endian == boost::endian::order::native)>
|
||||
{
|
||||
explicit is_contiguously_hashable() = default;
|
||||
};
|
||||
|
||||
template <class T, std::size_t N, class HashAlgorithm>
|
||||
struct is_contiguously_hashable<T[N], HashAlgorithm>
|
||||
: public std::integral_constant<
|
||||
bool,
|
||||
is_uniquely_represented<T[N]>::value &&
|
||||
(sizeof(T) == 1 ||
|
||||
HashAlgorithm::endian == boost::endian::order::native)>
|
||||
{
|
||||
explicit is_contiguously_hashable() = default;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Logically concatenate input data to a `Hasher`.
|
||||
|
||||
Hasher requirements:
|
||||
|
||||
`X` is the type `Hasher`
|
||||
`h` is a value of type `x`
|
||||
`p` is a value convertible to `void const*`
|
||||
`n` is a value of type `std::size_t`, greater than zero
|
||||
|
||||
Expression:
|
||||
`h.append (p, n);`
|
||||
Throws:
|
||||
Never
|
||||
Effect:
|
||||
Adds the input data to the hasher state.
|
||||
|
||||
Expression:
|
||||
`static_cast<std::size_t>(j)`
|
||||
Throws:
|
||||
Never
|
||||
Effect:
|
||||
Returns the reslting hash of all the input data.
|
||||
*/
|
||||
/** @{ */
|
||||
|
||||
// scalars
|
||||
|
||||
template <class Hasher, class T>
|
||||
inline std::enable_if_t<is_contiguously_hashable<T, Hasher>::value>
|
||||
hash_append(Hasher& h, T const& t) noexcept
|
||||
{
|
||||
h(std::addressof(t), sizeof(t));
|
||||
}
|
||||
|
||||
template <class Hasher, class T>
|
||||
inline std::enable_if_t<
|
||||
!is_contiguously_hashable<T, Hasher>::value &&
|
||||
(std::is_integral<T>::value || std::is_pointer<T>::value ||
|
||||
std::is_enum<T>::value)>
|
||||
hash_append(Hasher& h, T t) noexcept
|
||||
{
|
||||
detail::reverse_bytes(t);
|
||||
h(std::addressof(t), sizeof(t));
|
||||
}
|
||||
|
||||
template <class Hasher, class T>
|
||||
inline std::enable_if_t<std::is_floating_point<T>::value>
|
||||
hash_append(Hasher& h, T t) noexcept
|
||||
{
|
||||
if (t == 0)
|
||||
t = 0;
|
||||
detail::maybe_reverse_bytes(t, h);
|
||||
h(&t, sizeof(t));
|
||||
}
|
||||
|
||||
template <class Hasher>
|
||||
inline void
|
||||
hash_append(Hasher& h, std::nullptr_t) noexcept
|
||||
{
|
||||
void const* p = nullptr;
|
||||
detail::maybe_reverse_bytes(p, h);
|
||||
h(&p, sizeof(p));
|
||||
}
|
||||
|
||||
// Forward declarations for ADL purposes
|
||||
|
||||
template <class Hasher, class T, std::size_t N>
|
||||
std::enable_if_t<!is_contiguously_hashable<T, Hasher>::value>
|
||||
hash_append(Hasher& h, T (&a)[N]) noexcept;
|
||||
|
||||
template <class Hasher, class CharT, class Traits, class Alloc>
|
||||
std::enable_if_t<!is_contiguously_hashable<CharT, Hasher>::value>
|
||||
hash_append(
|
||||
Hasher& h,
|
||||
std::basic_string<CharT, Traits, Alloc> const& s) noexcept;
|
||||
|
||||
template <class Hasher, class CharT, class Traits, class Alloc>
|
||||
std::enable_if_t<is_contiguously_hashable<CharT, Hasher>::value>
|
||||
hash_append(
|
||||
Hasher& h,
|
||||
std::basic_string<CharT, Traits, Alloc> const& s) noexcept;
|
||||
|
||||
template <class Hasher, class T, class U>
|
||||
std::enable_if_t<!is_contiguously_hashable<std::pair<T, U>, Hasher>::value>
|
||||
hash_append(Hasher& h, std::pair<T, U> const& p) noexcept;
|
||||
|
||||
template <class Hasher, class T, class Alloc>
|
||||
std::enable_if_t<!is_contiguously_hashable<T, Hasher>::value>
|
||||
hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept;
|
||||
|
||||
template <class Hasher, class T, class Alloc>
|
||||
std::enable_if_t<is_contiguously_hashable<T, Hasher>::value>
|
||||
hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept;
|
||||
|
||||
template <class Hasher, class T, std::size_t N>
|
||||
std::enable_if_t<!is_contiguously_hashable<std::array<T, N>, Hasher>::value>
|
||||
hash_append(Hasher& h, std::array<T, N> const& a) noexcept;
|
||||
|
||||
template <class Hasher, class... T>
|
||||
std::enable_if_t<!is_contiguously_hashable<std::tuple<T...>, Hasher>::value>
|
||||
hash_append(Hasher& h, std::tuple<T...> const& t) noexcept;
|
||||
|
||||
template <class Hasher, class Key, class T, class Hash, class Pred, class Alloc>
|
||||
void
|
||||
hash_append(Hasher& h, std::unordered_map<Key, T, Hash, Pred, Alloc> const& m);
|
||||
|
||||
template <class Hasher, class Key, class Hash, class Pred, class Alloc>
|
||||
void
|
||||
hash_append(Hasher& h, std::unordered_set<Key, Hash, Pred, Alloc> const& s);
|
||||
|
||||
template <class Hasher, class Key, class Compare, class Alloc>
|
||||
std::enable_if_t<!is_contiguously_hashable<Key, Hasher>::value>
|
||||
hash_append(
|
||||
Hasher& h,
|
||||
boost::container::flat_set<Key, Compare, Alloc> const& v) noexcept;
|
||||
template <class Hasher, class Key, class Compare, class Alloc>
|
||||
std::enable_if_t<is_contiguously_hashable<Key, Hasher>::value>
|
||||
hash_append(
|
||||
Hasher& h,
|
||||
boost::container::flat_set<Key, Compare, Alloc> const& v) noexcept;
|
||||
template <class Hasher, class T0, class T1, class... T>
|
||||
void
|
||||
hash_append(Hasher& h, T0 const& t0, T1 const& t1, T const&... t) noexcept;
|
||||
|
||||
// c-array
|
||||
|
||||
template <class Hasher, class T, std::size_t N>
|
||||
std::enable_if_t<!is_contiguously_hashable<T, Hasher>::value>
|
||||
hash_append(Hasher& h, T (&a)[N]) noexcept
|
||||
{
|
||||
for (auto const& t : a)
|
||||
hash_append(h, t);
|
||||
}
|
||||
|
||||
// basic_string
|
||||
|
||||
template <class Hasher, class CharT, class Traits, class Alloc>
|
||||
inline std::enable_if_t<!is_contiguously_hashable<CharT, Hasher>::value>
|
||||
hash_append(
|
||||
Hasher& h,
|
||||
std::basic_string<CharT, Traits, Alloc> const& s) noexcept
|
||||
{
|
||||
for (auto c : s)
|
||||
hash_append(h, c);
|
||||
hash_append(h, s.size());
|
||||
}
|
||||
|
||||
template <class Hasher, class CharT, class Traits, class Alloc>
|
||||
inline std::enable_if_t<is_contiguously_hashable<CharT, Hasher>::value>
|
||||
hash_append(
|
||||
Hasher& h,
|
||||
std::basic_string<CharT, Traits, Alloc> const& s) noexcept
|
||||
{
|
||||
h(s.data(), s.size() * sizeof(CharT));
|
||||
hash_append(h, s.size());
|
||||
}
|
||||
|
||||
// pair
|
||||
|
||||
template <class Hasher, class T, class U>
|
||||
inline std::enable_if_t<
|
||||
!is_contiguously_hashable<std::pair<T, U>, Hasher>::value>
|
||||
hash_append(Hasher& h, std::pair<T, U> const& p) noexcept
|
||||
{
|
||||
hash_append(h, p.first, p.second);
|
||||
}
|
||||
|
||||
// vector
|
||||
|
||||
template <class Hasher, class T, class Alloc>
|
||||
inline std::enable_if_t<!is_contiguously_hashable<T, Hasher>::value>
|
||||
hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept
|
||||
{
|
||||
for (auto const& t : v)
|
||||
hash_append(h, t);
|
||||
hash_append(h, v.size());
|
||||
}
|
||||
|
||||
template <class Hasher, class T, class Alloc>
|
||||
inline std::enable_if_t<is_contiguously_hashable<T, Hasher>::value>
|
||||
hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept
|
||||
{
|
||||
h(v.data(), v.size() * sizeof(T));
|
||||
hash_append(h, v.size());
|
||||
}
|
||||
|
||||
// array
|
||||
|
||||
template <class Hasher, class T, std::size_t N>
|
||||
std::enable_if_t<!is_contiguously_hashable<std::array<T, N>, Hasher>::value>
|
||||
hash_append(Hasher& h, std::array<T, N> const& a) noexcept
|
||||
{
|
||||
for (auto const& t : a)
|
||||
hash_append(h, t);
|
||||
}
|
||||
|
||||
template <class Hasher, class Key, class Compare, class Alloc>
|
||||
std::enable_if_t<!is_contiguously_hashable<Key, Hasher>::value>
|
||||
hash_append(
|
||||
Hasher& h,
|
||||
boost::container::flat_set<Key, Compare, Alloc> const& v) noexcept
|
||||
{
|
||||
for (auto const& t : v)
|
||||
hash_append(h, t);
|
||||
}
|
||||
template <class Hasher, class Key, class Compare, class Alloc>
|
||||
std::enable_if_t<is_contiguously_hashable<Key, Hasher>::value>
|
||||
hash_append(
|
||||
Hasher& h,
|
||||
boost::container::flat_set<Key, Compare, Alloc> const& v) noexcept
|
||||
{
|
||||
h(&(v.begin()), v.size() * sizeof(Key));
|
||||
}
|
||||
// tuple
|
||||
|
||||
namespace detail {
|
||||
|
||||
inline void
|
||||
for_each_item(...) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
template <class Hasher, class T>
|
||||
inline int
|
||||
hash_one(Hasher& h, T const& t) noexcept
|
||||
{
|
||||
hash_append(h, t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Hasher, class... T, std::size_t... I>
|
||||
inline void
|
||||
tuple_hash(
|
||||
Hasher& h,
|
||||
std::tuple<T...> const& t,
|
||||
std::index_sequence<I...>) noexcept
|
||||
{
|
||||
for_each_item(hash_one(h, std::get<I>(t))...);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class Hasher, class... T>
|
||||
inline std::enable_if_t<
|
||||
!is_contiguously_hashable<std::tuple<T...>, Hasher>::value>
|
||||
hash_append(Hasher& h, std::tuple<T...> const& t) noexcept
|
||||
{
|
||||
detail::tuple_hash(h, t, std::index_sequence_for<T...>{});
|
||||
}
|
||||
|
||||
// shared_ptr
|
||||
|
||||
template <class Hasher, class T>
|
||||
inline void
|
||||
hash_append(Hasher& h, std::shared_ptr<T> const& p) noexcept
|
||||
{
|
||||
hash_append(h, p.get());
|
||||
}
|
||||
|
||||
// chrono
|
||||
|
||||
template <class Hasher, class Rep, class Period>
|
||||
inline void
|
||||
hash_append(Hasher& h, std::chrono::duration<Rep, Period> const& d) noexcept
|
||||
{
|
||||
hash_append(h, d.count());
|
||||
}
|
||||
|
||||
template <class Hasher, class Clock, class Duration>
|
||||
inline void
|
||||
hash_append(
|
||||
Hasher& h,
|
||||
std::chrono::time_point<Clock, Duration> const& tp) noexcept
|
||||
{
|
||||
hash_append(h, tp.time_since_epoch());
|
||||
}
|
||||
|
||||
// variadic
|
||||
|
||||
template <class Hasher, class T0, class T1, class... T>
|
||||
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...);
|
||||
}
|
||||
|
||||
// error_code
|
||||
|
||||
template <class HashAlgorithm>
|
||||
inline void
|
||||
hash_append(HashAlgorithm& h, std::error_code const& ec)
|
||||
{
|
||||
hash_append(h, ec.value(), &ec.category());
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
|
||||
#endif
|
||||
49
include/xrpl/beast/hash/uhash.h
Normal file
49
include/xrpl/beast/hash/uhash.h
Normal file
@@ -0,0 +1,49 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
|
||||
Vinnie Falco <vinnie.falco@gmail.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HASH_UHASH_H_INCLUDED
|
||||
#define BEAST_HASH_UHASH_H_INCLUDED
|
||||
|
||||
#include <ripple/beast/hash/hash_append.h>
|
||||
#include <ripple/beast/hash/xxhasher.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
// Universal hash function
|
||||
template <class Hasher = xxhasher>
|
||||
struct uhash
|
||||
{
|
||||
explicit uhash() = default;
|
||||
|
||||
using result_type = typename Hasher::result_type;
|
||||
|
||||
template <class T>
|
||||
result_type
|
||||
operator()(T const& t) const noexcept
|
||||
{
|
||||
Hasher h;
|
||||
hash_append(h, t);
|
||||
return static_cast<result_type>(h);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
|
||||
#endif
|
||||
101
include/xrpl/beast/hash/xxhasher.h
Normal file
101
include/xrpl/beast/hash/xxhasher.h
Normal file
@@ -0,0 +1,101 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HASH_XXHASHER_H_INCLUDED
|
||||
#define BEAST_HASH_XXHASHER_H_INCLUDED
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <xxhash.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class xxhasher
|
||||
{
|
||||
private:
|
||||
// requires 64-bit std::size_t
|
||||
static_assert(sizeof(std::size_t) == 8, "");
|
||||
|
||||
XXH3_state_t* state_;
|
||||
|
||||
static XXH3_state_t*
|
||||
allocState()
|
||||
{
|
||||
auto ret = XXH3_createState();
|
||||
if (ret == nullptr)
|
||||
throw std::bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public:
|
||||
using result_type = std::size_t;
|
||||
|
||||
static constexpr auto const endian = boost::endian::order::native;
|
||||
|
||||
xxhasher(xxhasher const&) = delete;
|
||||
xxhasher&
|
||||
operator=(xxhasher const&) = delete;
|
||||
|
||||
xxhasher()
|
||||
{
|
||||
state_ = allocState();
|
||||
XXH3_64bits_reset(state_);
|
||||
}
|
||||
|
||||
~xxhasher() noexcept
|
||||
{
|
||||
XXH3_freeState(state_);
|
||||
}
|
||||
|
||||
template <
|
||||
class Seed,
|
||||
std::enable_if_t<std::is_unsigned<Seed>::value>* = nullptr>
|
||||
explicit xxhasher(Seed seed)
|
||||
{
|
||||
state_ = allocState();
|
||||
XXH3_64bits_reset_withSeed(state_, seed);
|
||||
}
|
||||
|
||||
template <
|
||||
class Seed,
|
||||
std::enable_if_t<std::is_unsigned<Seed>::value>* = nullptr>
|
||||
xxhasher(Seed seed, Seed)
|
||||
{
|
||||
state_ = allocState();
|
||||
XXH3_64bits_reset_withSeed(state_, seed);
|
||||
}
|
||||
|
||||
void
|
||||
operator()(void const* key, std::size_t len) noexcept
|
||||
{
|
||||
XXH3_64bits_update(state_, key, len);
|
||||
}
|
||||
|
||||
explicit operator std::size_t() noexcept
|
||||
{
|
||||
return XXH3_64bits_digest(state_);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user