1 // Copyright 2005-2014 Daniel James.
2 // Distributed under the Boost Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4 //
5 // Based on Peter Dimov's proposal
6 // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
7 // issue 6.18.
8 //
9 // This also contains public domain code from MurmurHash. From the
10 // MurmurHash header:
11 //
12 // MurmurHash3 was written by Austin Appleby, and is placed in the public
13 // domain. The author hereby disclaims copyright to this source code.
14 //
15 // Copyright 2021 Ion Gaztanaga
16 // Refactored the original boost/container_hash/hash.hpp to avoid
17 // any heavy std header dependencies to just combine two hash
18 // values represented in a std::size_t type.
19
20 #ifndef BOOST_INTRUSIVE_DETAIL_HASH_COMBINE_HPP
21 #define BOOST_INTRUSIVE_DETAIL_HASH_COMBINE_HPP
22
23 #ifndef BOOST_CONFIG_HPP
24 # include <boost/config.hpp>
25 #endif
26
27 #if defined(BOOST_HAS_PRAGMA_ONCE)
28 # pragma once
29 #endif
30
31 #include <boost/cstdint.hpp>
32
33 #if defined(_MSC_VER)
34 # include <stdlib.h>
35 # define BOOST_INTRUSIVE_HASH_ROTL32(x, r) _rotl(x,r)
36 #else
37 # define BOOST_INTRUSIVE_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r))
38 #endif
39
40 namespace boost {
41 namespace intrusive {
42 namespace detail {
43
44 template <typename SizeT>
hash_combine_size_t(SizeT & seed,SizeT value)45 inline void hash_combine_size_t(SizeT& seed, SizeT value)
46 {
47 seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
48 }
49
hash_combine_size_t(boost::uint32_t & h1,boost::uint32_t k1)50 inline void hash_combine_size_t(boost::uint32_t& h1,
51 boost::uint32_t k1)
52 {
53 const uint32_t c1 = 0xcc9e2d51;
54 const uint32_t c2 = 0x1b873593;
55
56 k1 *= c1;
57 k1 = BOOST_INTRUSIVE_HASH_ROTL32(k1,15);
58 k1 *= c2;
59
60 h1 ^= k1;
61 h1 = BOOST_INTRUSIVE_HASH_ROTL32(h1,13);
62 h1 = h1*5+0xe6546b64;
63 }
64
65
66 // Don't define 64-bit hash combine on platforms without 64 bit integers,
67 // and also not for 32-bit gcc as it warns about the 64-bit constant.
68 #if !defined(BOOST_NO_INT64_T) && \
69 !(defined(__GNUC__) && ULONG_MAX == 0xffffffff)
hash_combine_size_t(boost::uint64_t & h,boost::uint64_t k)70 inline void hash_combine_size_t(boost::uint64_t& h,
71 boost::uint64_t k)
72 {
73 const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995);
74 const int r = 47;
75
76 k *= m;
77 k ^= k >> r;
78 k *= m;
79
80 h ^= k;
81 h *= m;
82
83 // Completely arbitrary number, to prevent 0's
84 // from hashing to 0.
85 h += 0xe6546b64;
86 }
87
88 #endif // BOOST_NO_INT64_T
89
90 } //namespace detail {
91 } //namespace intrusive {
92 } //namespace boost {
93
94 #endif //BOOST_INTRUSIVE_DETAIL_HASH_COMBINE_HPP
95