]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
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> | |
45 | inline void hash_combine_size_t(SizeT& seed, SizeT value) | |
46 | { | |
47 | seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2); | |
48 | } | |
49 | ||
50 | inline void hash_combine_size_t(boost::uint32_t& h1, boost::uint32_t k1) | |
51 | { | |
52 | const uint32_t c1 = 0xcc9e2d51; | |
53 | const uint32_t c2 = 0x1b873593; | |
54 | ||
55 | k1 *= c1; | |
56 | k1 = BOOST_INTRUSIVE_HASH_ROTL32(k1,15); | |
57 | k1 *= c2; | |
58 | ||
59 | h1 ^= k1; | |
60 | h1 = BOOST_INTRUSIVE_HASH_ROTL32(h1,13); | |
61 | h1 = h1*5+0xe6546b64; | |
62 | } | |
63 | ||
64 | ||
65 | // Don't define 64-bit hash combine on platforms without 64 bit integers, | |
66 | // and also not for 32-bit gcc as it warns about the 64-bit constant. | |
67 | #if !defined(BOOST_NO_INT64_T) && \ | |
68 | !(defined(__GNUC__) && ULONG_MAX == 0xffffffff) | |
69 | inline void hash_combine_size_t(boost::uint64_t& h, boost::uint64_t k) | |
70 | { | |
71 | const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995); | |
72 | const int r = 47; | |
73 | ||
74 | k *= m; | |
75 | k ^= k >> r; | |
76 | k *= m; | |
77 | ||
78 | h ^= k; | |
79 | h *= m; | |
80 | ||
81 | // Completely arbitrary number, to prevent 0's | |
82 | // from hashing to 0. | |
83 | h += 0xe6546b64; | |
84 | } | |
85 | ||
86 | #endif // BOOST_NO_INT64_T | |
87 | ||
88 | } //namespace detail { | |
89 | } //namespace intrusive { | |
90 | } //namespace boost { | |
91 | ||
92 | #endif //BOOST_INTRUSIVE_DETAIL_HASH_COMBINE_HPP |