mirror of
https://github.com/boostorg/container_hash.git
synced 2025-08-04 06:54:38 +02:00
Feature/hash_is_avalanching (#40)
* added hash_is_avalanching * launched CI after enabling GHA * moved 1.89 entry from Change Log to Recent Changes * segregated some tests into hash_is_avalanching_test3.cpp and gotten rid of Unordered dependency * removed unneeded include * stopped using external std::hash for testing * typo * removed left over include * typo * moved hash_is_avalanching from boost::container_hash to boost * fixed specializations of boost::hash_is_avalanching
This commit is contained in:
@@ -8,6 +8,10 @@ https://www.boost.org/LICENSE_1_0.txt
|
|||||||
= Recent Changes
|
= Recent Changes
|
||||||
:idprefix: recent_
|
:idprefix: recent_
|
||||||
|
|
||||||
|
== Boost 1.89.0
|
||||||
|
|
||||||
|
* Added the `hash_is_avalanching` trait class.
|
||||||
|
|
||||||
== Boost 1.84.0
|
== Boost 1.84.0
|
||||||
|
|
||||||
* {cpp}03 is no longer supported.
|
* {cpp}03 is no longer supported.
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
////
|
////
|
||||||
Copyright 2005-2008 Daniel James
|
Copyright 2005-2008 Daniel James
|
||||||
Copyright 2022 Christian Mazakas
|
Copyright 2022 Christian Mazakas
|
||||||
Copyright 2022 Peter Dimov
|
Copyright 2022, 2025 Peter Dimov
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
https://www.boost.org/LICENSE_1_0.txt
|
https://www.boost.org/LICENSE_1_0.txt
|
||||||
////
|
////
|
||||||
@@ -44,6 +44,8 @@ template<class It> std::size_t hash_range( It first, It last );
|
|||||||
template<class It> void hash_unordered_range( std::size_t& seed, It first, It last );
|
template<class It> void hash_unordered_range( std::size_t& seed, It first, It last );
|
||||||
template<class It> std::size_t hash_unordered_range( It first, It last );
|
template<class It> std::size_t hash_unordered_range( It first, It last );
|
||||||
|
|
||||||
|
template<class Hash> struct hash_is_avalanching;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
----
|
----
|
||||||
|
|
||||||
@@ -572,6 +574,56 @@ where `x` is the currently contained value in `v`.
|
|||||||
Throws: ::
|
Throws: ::
|
||||||
`std::bad_variant_access` when `v.valueless_by_exception()` is `true`.
|
`std::bad_variant_access` when `v.valueless_by_exception()` is `true`.
|
||||||
|
|
||||||
|
== <boost/container_hash/{zwsp}hash_is_avalanching.hpp>
|
||||||
|
|
||||||
|
Defines the trait `boost::hash_is_avalanching`.
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class Hash> struct hash_is_avalanching;
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
----
|
||||||
|
|
||||||
|
=== hash_is_avalanching<Hash>
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
template<class Hash> struct hash_is_avalanching
|
||||||
|
{
|
||||||
|
static constexpr bool value = /* see below */;
|
||||||
|
};
|
||||||
|
----
|
||||||
|
|
||||||
|
`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),
|
||||||
|
* ill-formed otherwise.
|
||||||
|
|
||||||
|
A hash function is said to have the _avalanching property_ if small changes
|
||||||
|
in the input translate to large changes in the returned hash code
|
||||||
|
—ideally, flipping one bit in the representation of the input value results
|
||||||
|
in each bit of the hash code flipping with probability 50%. Libraries
|
||||||
|
such as link:../../../unordered/index.html[Boost.Unordered] consult this trait
|
||||||
|
to determine if the supplied hash function is of high quality.
|
||||||
|
`boost::hash` for `std::basic_string<Ch>` and `std::basic_string_view<Ch>`
|
||||||
|
has this trait set to `true` when `Ch` is an integral type (this includes
|
||||||
|
`std::string` and `std::string_view`, among others).
|
||||||
|
Users can set this trait for a particular `Hash` type by:
|
||||||
|
|
||||||
|
* Inserting the nested `is_avalanching` typedef in the class definition
|
||||||
|
if they have access to its source code.
|
||||||
|
* Writing a specialization of `boost::hash_is_avalanching`
|
||||||
|
for `Hash`.
|
||||||
|
|
||||||
|
Note that usage of this trait is not restricted to hash functions produced
|
||||||
|
with Boost.ContainerHash.
|
||||||
|
|
||||||
== <boost/container_hash/{zwsp}is_range.hpp>
|
== <boost/container_hash/{zwsp}is_range.hpp>
|
||||||
|
|
||||||
Defines the trait `boost::container_hash::is_range`.
|
Defines the trait `boost::container_hash::is_range`.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Copyright 2005-2014 Daniel James.
|
// Copyright 2005-2014 Daniel James.
|
||||||
// Copyright 2021, 2022 Peter Dimov.
|
// Copyright 2021, 2022, 2025 Peter Dimov.
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// https://www.boost.org/LICENSE_1_0.txt
|
// https://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
|
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
|
||||||
|
|
||||||
#include <boost/container_hash/hash_fwd.hpp>
|
#include <boost/container_hash/hash_fwd.hpp>
|
||||||
|
#include <boost/container_hash/hash_is_avalanching.hpp>
|
||||||
#include <boost/container_hash/is_range.hpp>
|
#include <boost/container_hash/is_range.hpp>
|
||||||
#include <boost/container_hash/is_contiguous_range.hpp>
|
#include <boost/container_hash/is_contiguous_range.hpp>
|
||||||
#include <boost/container_hash/is_unordered_range.hpp>
|
#include <boost/container_hash/is_unordered_range.hpp>
|
||||||
@@ -557,19 +558,15 @@ namespace boost
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// boost::unordered::hash_is_avalanching
|
// hash_is_avalanching
|
||||||
|
|
||||||
namespace unordered
|
template<class Ch> struct hash_is_avalanching< boost::hash< std::basic_string<Ch> > >: std::is_integral<Ch> {};
|
||||||
{
|
|
||||||
template<class T> struct hash_is_avalanching;
|
|
||||||
template<class Ch> struct hash_is_avalanching< boost::hash< std::basic_string<Ch> > >: std::is_integral<Ch> {};
|
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
|
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
|
||||||
|
|
||||||
template<class Ch> struct hash_is_avalanching< boost::hash< std::basic_string_view<Ch> > >: std::is_integral<Ch> {};
|
template<class Ch> struct hash_is_avalanching< boost::hash< std::basic_string_view<Ch> > >: std::is_integral<Ch> {};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
} // namespace unordered
|
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Copyright 2005-2009 Daniel James.
|
// Copyright 2005-2009 Daniel James.
|
||||||
// Copyright 2021, 2022 Peter Dimov.
|
// Copyright 2021, 2022, 2025 Peter Dimov.
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// https://www.boost.org/LICENSE_1_0.txt
|
// https://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
@@ -32,6 +32,8 @@ template<class It> std::size_t hash_range( It, It );
|
|||||||
template<class It> void hash_unordered_range( std::size_t&, It, It );
|
template<class It> void hash_unordered_range( std::size_t&, It, It );
|
||||||
template<class It> std::size_t hash_unordered_range( It, It );
|
template<class It> std::size_t hash_unordered_range( It, It );
|
||||||
|
|
||||||
|
template<class Hash> struct hash_is_avalanching;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_FUNCTIONAL_HASH_FWD_HPP
|
#endif // #ifndef BOOST_FUNCTIONAL_HASH_FWD_HPP
|
||||||
|
57
include/boost/container_hash/hash_is_avalanching.hpp
Normal file
57
include/boost/container_hash/hash_is_avalanching.hpp
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// Copyright 2025 Joaquin M Lopez Munoz.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
#ifndef BOOST_HASH_HASH_IS_AVALANCHING_HPP_INCLUDED
|
||||||
|
#define BOOST_HASH_HASH_IS_AVALANCHING_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace hash_detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class... Ts> struct make_void
|
||||||
|
{
|
||||||
|
using type = void;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class... Ts> using void_t = typename make_void<Ts...>::type;
|
||||||
|
|
||||||
|
template<class 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<class Hash, class = void> struct hash_is_avalanching_impl: std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Hash> struct hash_is_avalanching_impl<Hash, void_t<typename Hash::is_avalanching> >:
|
||||||
|
std::integral_constant<bool, avalanching_value<typename Hash::is_avalanching>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Hash>
|
||||||
|
struct hash_is_avalanching_impl<Hash, typename std::enable_if< ((void)Hash::is_avalanching, true) >::type>
|
||||||
|
{
|
||||||
|
// Hash::is_avalanching is not a type: we don't define value to produce
|
||||||
|
// a compile error downstream
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace hash_detail
|
||||||
|
|
||||||
|
template<class Hash> struct hash_is_avalanching: hash_detail::hash_is_avalanching_impl<Hash>::type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_HASH_HASH_IS_AVALANCHING_HPP_INCLUDED
|
@@ -1,4 +1,4 @@
|
|||||||
# Copyright 2018, 2019, 2021, 2022 Peter Dimov
|
# Copyright 2018, 2019, 2021, 2022, 2025 Peter Dimov
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
# 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
|
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
@@ -7,6 +7,6 @@ include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
|
|||||||
if(HAVE_BOOST_TEST)
|
if(HAVE_BOOST_TEST)
|
||||||
|
|
||||||
boost_test_jamfile(FILE Jamfile.v2
|
boost_test_jamfile(FILE Jamfile.v2
|
||||||
LINK_LIBRARIES Boost::container_hash Boost::core Boost::utility Boost::unordered)
|
LINK_LIBRARIES Boost::container_hash Boost::core Boost::utility)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
# Copyright 2005-2012 Daniel James.
|
# Copyright 2005-2012 Daniel James.
|
||||||
# Copyright 2022 Peter Dimov
|
# Copyright 2022, 2025 Peter Dimov
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
# Distributed under the Boost Software License, Version 1.0.
|
||||||
# https://www.boost.org/LICENSE_1_0.txt
|
# https://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
@@ -119,10 +119,9 @@ run is_described_class_test3.cpp
|
|||||||
run described_class_test.cpp
|
run described_class_test.cpp
|
||||||
: : : <warnings>extra ;
|
: : : <warnings>extra ;
|
||||||
|
|
||||||
run hash_is_avalanching_test.cpp
|
run hash_is_avalanching_test.cpp ;
|
||||||
/boost/unordered//boost_unordered ;
|
run hash_is_avalanching_test2.cpp ;
|
||||||
run hash_is_avalanching_test2.cpp
|
run hash_is_avalanching_test3.cpp ;
|
||||||
/boost/unordered//boost_unordered ;
|
|
||||||
|
|
||||||
run hash_integral_test2.cpp ;
|
run hash_integral_test2.cpp ;
|
||||||
|
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
// Copyright 2022 Peter Dimov.
|
// Copyright 2022, 2025 Peter Dimov.
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// https://www.boost.org/LICENSE_1_0.txt
|
// https://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
#include <boost/container_hash/hash.hpp>
|
#include <boost/container_hash/hash.hpp>
|
||||||
|
#include <boost/container_hash/hash_is_avalanching.hpp>
|
||||||
#include <boost/core/lightweight_test_trait.hpp>
|
#include <boost/core/lightweight_test_trait.hpp>
|
||||||
#include <boost/unordered/hash_traits.hpp>
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ enum my_char { min = 0, max = 255 };
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::unordered::hash_is_avalanching;
|
using boost::hash_is_avalanching;
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE(( hash_is_avalanching< boost::hash<std::string> > ));
|
BOOST_TEST_TRAIT_TRUE(( hash_is_avalanching< boost::hash<std::string> > ));
|
||||||
BOOST_TEST_TRAIT_TRUE(( hash_is_avalanching< boost::hash<std::wstring> > ));
|
BOOST_TEST_TRAIT_TRUE(( hash_is_avalanching< boost::hash<std::wstring> > ));
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
// Copyright 2022 Peter Dimov.
|
// Copyright 2022, 2025 Peter Dimov.
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// https://www.boost.org/LICENSE_1_0.txt
|
// https://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
#include <boost/container_hash/hash.hpp>
|
#include <boost/container_hash/hash.hpp>
|
||||||
|
#include <boost/container_hash/hash_is_avalanching.hpp>
|
||||||
#include <boost/core/lightweight_test_trait.hpp>
|
#include <boost/core/lightweight_test_trait.hpp>
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/config/pragma_message.hpp>
|
#include <boost/config/pragma_message.hpp>
|
||||||
@@ -14,14 +15,13 @@ int main() {}
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <boost/unordered/hash_traits.hpp>
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
enum my_char { min = 0, max = 255 };
|
enum my_char { min = 0, max = 255 };
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::unordered::hash_is_avalanching;
|
using boost::hash_is_avalanching;
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE(( hash_is_avalanching< boost::hash<std::string_view> > ));
|
BOOST_TEST_TRAIT_TRUE(( hash_is_avalanching< boost::hash<std::string_view> > ));
|
||||||
BOOST_TEST_TRAIT_TRUE(( hash_is_avalanching< boost::hash<std::wstring_view> > ));
|
BOOST_TEST_TRAIT_TRUE(( hash_is_avalanching< boost::hash<std::wstring_view> > ));
|
||||||
|
38
test/hash_is_avalanching_test3.cpp
Normal file
38
test/hash_is_avalanching_test3.cpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2025 Joaquin M Lopez Munoz.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
#include <boost/container_hash/hash_is_avalanching.hpp>
|
||||||
|
#include <boost/core/lightweight_test_trait.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
using is_avalanching = void;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Y
|
||||||
|
{
|
||||||
|
using is_avalanching = std::true_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Z
|
||||||
|
{
|
||||||
|
using is_avalanching = std::false_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct W
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
using boost::hash_is_avalanching;
|
||||||
|
|
||||||
|
BOOST_TEST_TRAIT_TRUE(( hash_is_avalanching< X > ));
|
||||||
|
BOOST_TEST_TRAIT_TRUE(( hash_is_avalanching< Y > ));
|
||||||
|
BOOST_TEST_TRAIT_FALSE(( hash_is_avalanching< Z > ));
|
||||||
|
BOOST_TEST_TRAIT_FALSE(( hash_is_avalanching< W > ));
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
Reference in New Issue
Block a user