Compare commits

...

6 Commits

Author SHA1 Message Date
Peter Dimov
c8dab7f85a Remove windows-2019 from GHA 2025-08-21 18:22:07 +03:00
Peter Dimov
5d8b8ac2b9 Add gcc-15, clang-20 to ci.yml 2025-06-09 00:05:15 +03:00
Peter Dimov
1e1cf6c46e Update ci.yml 2025-06-09 00:00:37 +03:00
Peter Dimov
88aacb6d46 Remove trailing whitespace 2025-06-08 23:23:14 +03:00
joaquintides
0a000167b7 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
2025-05-28 12:05:10 +03:00
Peter Dimov
d8f1075080 Update ci.yml 2025-05-27 11:55:45 +03:00
11 changed files with 220 additions and 57 deletions

View File

@@ -19,35 +19,38 @@ jobs:
include:
- toolset: gcc-4.8
cxxstd: "11"
os: ubuntu-latest
container: ubuntu:18.04
os: ubuntu-latest
install: g++-4.8-multilib
address-model: 32,64
- toolset: gcc-5
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
os: ubuntu-latest
install: g++-5-multilib
address-model: 32,64
- toolset: gcc-6
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
os: ubuntu-latest
install: g++-6-multilib
address-model: 32,64
- toolset: gcc-7
cxxstd: "11,14,17"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: g++-7-multilib
address-model: 32,64
- toolset: gcc-8
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: g++-8-multilib
address-model: 32,64
- toolset: gcc-9
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: g++-9-multilib
address-model: 32,64
- toolset: gcc-10
@@ -67,66 +70,82 @@ jobs:
address-model: 32,64
- toolset: gcc-13
cxxstd: "11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:24.04
os: ubuntu-latest
install: g++-13-multilib
address-model: 32,64
- toolset: gcc-14
cxxstd: "11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:24.04
os: ubuntu-latest
install: g++-14-multilib
address-model: 32,64
- toolset: gcc-15
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:25.04
os: ubuntu-latest
install: g++-15-multilib
address-model: 32,64
- toolset: clang
compiler: clang++-3.9
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
os: ubuntu-latest
install: clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
os: ubuntu-latest
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
os: ubuntu-latest
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "11,14,17"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "11,14,17"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "11,14,17"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-8
- toolset: clang
compiler: clang++-9
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "11,14,17,20"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-12
- toolset: clang
compiler: clang++-13
cxxstd: "11,14,17,20,2b"
@@ -166,9 +185,15 @@ jobs:
- toolset: clang
compiler: clang++-19
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.10
container: ubuntu:24.04
os: ubuntu-latest
install: clang-19
- toolset: clang
compiler: clang++-20
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:25.04
os: ubuntu-latest
install: clang-20
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-13
@@ -252,14 +277,6 @@ jobs:
fail-fast: false
matrix:
include:
- toolset: msvc-14.0
cxxstd: 14,latest
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.2
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
@@ -271,7 +288,7 @@ jobs:
- toolset: gcc
cxxstd: "11,14,17,2a"
addrmd: 64
os: windows-2019
os: windows-2022
runs-on: ${{matrix.os}}
@@ -312,7 +329,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: ubuntu-24.04
- os: macos-13
@@ -361,7 +377,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: ubuntu-24.04
- os: macos-13
@@ -420,7 +435,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: ubuntu-24.04
- os: macos-13
@@ -477,8 +491,8 @@ jobs:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
- os: windows-2025
runs-on: ${{matrix.os}}
@@ -526,8 +540,8 @@ jobs:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
- os: windows-2025
runs-on: ${{matrix.os}}
@@ -593,8 +607,8 @@ jobs:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
- os: windows-2025
runs-on: ${{matrix.os}}

View File

@@ -8,6 +8,10 @@ https://www.boost.org/LICENSE_1_0.txt
= Recent Changes
:idprefix: recent_
== Boost 1.89.0
* Added the `hash_is_avalanching` trait class.
== Boost 1.84.0
* {cpp}03 is no longer supported.

View File

@@ -1,7 +1,7 @@
////
Copyright 2005-2008 Daniel James
Copyright 2022 Christian Mazakas
Copyright 2022 Peter Dimov
Copyright 2022, 2025 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
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> std::size_t hash_unordered_range( It first, It last );
template<class Hash> struct hash_is_avalanching;
} // namespace boost
----
@@ -572,6 +574,56 @@ where `x` is the currently contained value in `v`.
Throws: ::
`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
&#8212;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>
Defines the trait `boost::container_hash::is_range`.

View File

@@ -1,5 +1,5 @@
// 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.
// https://www.boost.org/LICENSE_1_0.txt
@@ -11,6 +11,7 @@
#define BOOST_FUNCTIONAL_HASH_HASH_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_contiguous_range.hpp>
#include <boost/container_hash/is_unordered_range.hpp>
@@ -557,19 +558,15 @@ namespace boost
#endif
// boost::unordered::hash_is_avalanching
// hash_is_avalanching
namespace unordered
{
template<class T> struct hash_is_avalanching;
template<class Ch> struct hash_is_avalanching< boost::hash< std::basic_string<Ch> > >: std::is_integral<Ch> {};
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)
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
} // namespace unordered
} // namespace boost

View File

@@ -1,5 +1,5 @@
// 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.
// 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> std::size_t hash_unordered_range( It, It );
template<class Hash> struct hash_is_avalanching;
} // namespace boost
#endif // #ifndef BOOST_FUNCTIONAL_HASH_FWD_HPP

View 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

View File

@@ -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.
# 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)
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()

View File

@@ -1,5 +1,5 @@
# Copyright 2005-2012 Daniel James.
# Copyright 2022 Peter Dimov
# Copyright 2022, 2025 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
@@ -119,10 +119,9 @@ run is_described_class_test3.cpp
run described_class_test.cpp
: : : <warnings>extra ;
run hash_is_avalanching_test.cpp
/boost/unordered//boost_unordered ;
run hash_is_avalanching_test2.cpp
/boost/unordered//boost_unordered ;
run hash_is_avalanching_test.cpp ;
run hash_is_avalanching_test2.cpp ;
run hash_is_avalanching_test3.cpp ;
run hash_integral_test2.cpp ;

View File

@@ -1,10 +1,10 @@
// Copyright 2022 Peter Dimov.
// Copyright 2022, 2025 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/container_hash/hash.hpp>
#include <boost/container_hash/hash_is_avalanching.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/unordered/hash_traits.hpp>
#include <boost/config.hpp>
#include <string>
@@ -12,7 +12,7 @@ enum my_char { min = 0, max = 255 };
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::wstring> > ));

View File

@@ -1,8 +1,9 @@
// Copyright 2022 Peter Dimov.
// Copyright 2022, 2025 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/container_hash/hash.hpp>
#include <boost/container_hash/hash_is_avalanching.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
@@ -14,14 +15,13 @@ int main() {}
#else
#include <boost/unordered/hash_traits.hpp>
#include <string_view>
enum my_char { min = 0, max = 255 };
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::wstring_view> > ));

View 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();
}