mirror of
https://github.com/boostorg/unordered.git
synced 2025-05-09 23:23:59 +00:00
updated is_avalanching trait protocol
This commit is contained in:
parent
6745d67d62
commit
f77bdb9b67
@ -1,5 +1,5 @@
|
||||
// Copyright 2021 Peter Dimov.
|
||||
// Copyright 2023 Joaquin M Lopez Munoz.
|
||||
// Copyright 2023-2024 Joaquin M Lopez Munoz.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#include <type_traits>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
@ -341,7 +342,7 @@ template<> struct fnv1a_hash_impl<64>
|
||||
|
||||
struct fnv1a_hash: fnv1a_hash_impl< std::numeric_limits<std::size_t>::digits >
|
||||
{
|
||||
using is_avalanching = void;
|
||||
using is_avalanching = std::true_type;
|
||||
};
|
||||
|
||||
template<class K, class V> using std_unordered_map_fnv1a =
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#include <type_traits>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
@ -262,7 +263,7 @@ template<> struct fnv1a_hash_impl<64>
|
||||
|
||||
struct fnv1a_hash: fnv1a_hash_impl< std::numeric_limits<std::size_t>::digits >
|
||||
{
|
||||
using is_avalanching = void;
|
||||
using is_avalanching = std::true_type;
|
||||
};
|
||||
|
||||
template<class K, class V> using boost_unordered_flat_map_fnv1a =
|
||||
@ -272,7 +273,7 @@ template<class K, class V> using boost_unordered_flat_map_fnv1a =
|
||||
|
||||
struct slightly_bad_hash
|
||||
{
|
||||
using is_avalanching = void;
|
||||
using is_avalanching = std::true_type;
|
||||
|
||||
std::size_t operator()( std::string const& s ) const
|
||||
{
|
||||
@ -295,7 +296,7 @@ template<class K, class V> using boost_unordered_flat_map_slightly_bad_hash =
|
||||
|
||||
struct bad_hash
|
||||
{
|
||||
using is_avalanching = void;
|
||||
using is_avalanching = std::true_type;
|
||||
|
||||
std::size_t operator()( std::string const& s ) const
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright 2021 Peter Dimov.
|
||||
// Copyright 2023 Joaquin M Lopez Munoz.
|
||||
// Copyright 2023-2024 Joaquin M Lopez Munoz.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#include <type_traits>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
@ -342,7 +343,7 @@ template<> struct fnv1a_hash_impl<64>
|
||||
|
||||
struct fnv1a_hash: fnv1a_hash_impl< std::numeric_limits<std::size_t>::digits >
|
||||
{
|
||||
using is_avalanching = void;
|
||||
using is_avalanching = std::true_type;
|
||||
};
|
||||
|
||||
template<class K, class V> using std_unordered_map_fnv1a =
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
* Added container `pmr` aliases when header `<memory_resource>` is available. The alias `boost::unordered::pmr::[container]` refers to `boost::unordered::[container]` with a `std::pmr::polymorphic_allocator` allocator type.
|
||||
* Equipped open-addressing and concurrent containers to internally calculate and provide statistical metrics affected by the quality of the hash function. This functionality is enabled by the global macro `BOOST_UNORDERED_ENABLE_STATS`.
|
||||
* Avalanching hash functions must now be marked via an `is_avalanching` typedef with an embedded `value` constant set to `true` (typically, defining `is_avalanching` as `std::true_type`). `using is_avalanching = void` is deprecated but allowed for backwards compatibility.
|
||||
|
||||
== Release 1.85.0
|
||||
|
||||
|
@ -33,7 +33,7 @@ follows:
|
||||
----
|
||||
struct my_string_hash_function
|
||||
{
|
||||
using is_avalanching = void; // instruct Boost.Unordered to not use post-mixing
|
||||
using is_avalanching = std::true_type; // instruct Boost.Unordered to not use post-mixing
|
||||
|
||||
std::size_t operator()(const std::string& x) const
|
||||
{
|
||||
|
@ -32,9 +32,14 @@ large changes in the returned hash code —ideally, flipping one bit in the
|
||||
the input value results in each bit of the hash code flipping with probability 50%. Approaching
|
||||
this property is critical for the proper behavior of open-addressing hash containers.
|
||||
|
||||
`hash_is_avalanching<Hash>::value` is `true` if `Hash::is_avalanching` is a valid type,
|
||||
and `false` otherwise.
|
||||
Users can then declare a hash function `Hash` as avalanching either by embedding an `is_avalanching` typedef
|
||||
`hash_is_avalanching<Hash>::value` is:
|
||||
|
||||
* `false` if `Hash::is_avalanching` is not present,
|
||||
* `Hash::is_avalanching::value` if this is present and convertible at compile time to a `bool`,
|
||||
* `true` if `Hash::is_avalanching` is `void` (this usage is deprecated).
|
||||
|
||||
The behavior is undefined if none of the three cases above is met.
|
||||
Users can then declare a hash function `Hash` as avalanching either by embedding an appropriate `is_avalanching` typedef
|
||||
into the definition of `Hash`, or directly by specializing `hash_is_avalanching<Hash>` to a class with
|
||||
an embedded compile-time constant `value` set to `true`.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Hash function characterization.
|
||||
*
|
||||
* Copyright 2022 Joaquin M Lopez Munoz.
|
||||
* Copyright 2022-2024 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -19,12 +19,28 @@ namespace unordered{
|
||||
namespace detail{
|
||||
|
||||
template<typename Hash,typename=void>
|
||||
struct hash_is_avalanching_impl: std::false_type{};
|
||||
struct hash_is_avalanching_impl:std::false_type{};
|
||||
|
||||
template<typename IsAvalanching>
|
||||
struct avalanching_value
|
||||
{
|
||||
static constexpr bool value=IsAvalanching::value;
|
||||
};
|
||||
|
||||
/* may be explicitly marked as BOOST_DEPRECATED in the future */
|
||||
template<> struct avalanching_value<void>
|
||||
{
|
||||
static constexpr bool value=true;
|
||||
};
|
||||
|
||||
template<typename Hash>
|
||||
struct hash_is_avalanching_impl<Hash,
|
||||
boost::unordered::detail::void_t<typename Hash::is_avalanching> >:
|
||||
std::true_type{};
|
||||
struct hash_is_avalanching_impl<
|
||||
Hash,
|
||||
boost::unordered::detail::void_t<typename Hash::is_avalanching>
|
||||
>:std::integral_constant<
|
||||
bool,
|
||||
avalanching_value<typename Hash::is_avalanching>::value
|
||||
>{};
|
||||
|
||||
} /* namespace detail */
|
||||
|
||||
@ -32,8 +48,12 @@ struct hash_is_avalanching_impl<Hash,
|
||||
* when actual characterization differs from default.
|
||||
*/
|
||||
|
||||
/* hash_is_avalanching<Hash>::value is true when the type Hash::is_avalanching
|
||||
* is present, false otherwise.
|
||||
/* hash_is_avalanching<Hash>::value is:
|
||||
* - false if Hash::is_avalanching is not present.
|
||||
* - Hash::is_avalanching::value if this is present and constexpr-convertible
|
||||
* to a bool.
|
||||
* - true if Hash::is_avalanching is void (deprecated).
|
||||
* UB otherwise.
|
||||
*/
|
||||
template<typename Hash>
|
||||
struct hash_is_avalanching: detail::hash_is_avalanching_impl<Hash>::type{};
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Copyright 2024 Joaquin M Lopez Munoz
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
@ -26,6 +27,7 @@ namespace unordered
|
||||
|
||||
#include <boost/unordered/hash_traits.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
struct X1
|
||||
{
|
||||
@ -36,6 +38,27 @@ struct X2
|
||||
typedef void is_avalanching;
|
||||
};
|
||||
|
||||
struct X4
|
||||
{
|
||||
using is_avalanching = std::false_type;
|
||||
};
|
||||
|
||||
struct X5
|
||||
{
|
||||
using is_avalanching = std::true_type;
|
||||
};
|
||||
|
||||
struct X6
|
||||
{
|
||||
using is_avalanching = boost::false_type;
|
||||
};
|
||||
|
||||
struct X7
|
||||
{
|
||||
using is_avalanching = boost::true_type;
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::unordered::hash_is_avalanching;
|
||||
@ -43,6 +66,10 @@ int main()
|
||||
BOOST_TEST_TRAIT_FALSE((hash_is_avalanching<X1>));
|
||||
BOOST_TEST_TRAIT_TRUE((hash_is_avalanching<X2>));
|
||||
BOOST_TEST_TRAIT_TRUE((hash_is_avalanching<X3>));
|
||||
BOOST_TEST_TRAIT_FALSE((hash_is_avalanching<X4>));
|
||||
BOOST_TEST_TRAIT_TRUE((hash_is_avalanching<X5>));
|
||||
BOOST_TEST_TRAIT_FALSE((hash_is_avalanching<X6>));
|
||||
BOOST_TEST_TRAIT_TRUE((hash_is_avalanching<X7>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user