1 /*
2 ** Copyright 2012-2013 Centreon
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 **
16 ** For more information : contact@centreon.com
17 */
18
19 #ifndef CC_HASH_HH
20 #define CC_HASH_HH
21
22 #if __cplusplus == 201103L
23 #define CXX0X_UNORDERED 1
24 #elif defined(__clang__)
25 #if __has_feature(cxx_variadic_templates)
26 #define TR1_UNORDERED 1
27 #endif // cxx_variadic_templates.
28 #elif defined(__GNUC__) && __GNUC__ >= 4
29 #define TR1_UNORDERED 1
30 #endif // C++0x, tr1
31
32 #include "com/centreon/namespace.hh"
33
34 // Used c++0x implementation.
35 #ifdef CXX0X_UNORDERED
36 #include <functional>
37
CC_BEGIN()38 CC_BEGIN()
39
40 template <typename T>
41 std::size_t hash(T const& data) {
42 std::hash<T> h;
43 return (h(data));
44 }
45
46 CC_END()
47
48 // Used tr1 implementation.
49 #elif defined(TR1_UNORDERED)
50 #include <tr1/functional>
51
52 CC_BEGIN()
53
54 template <typename T>
55 std::size_t hash(T const& data) {
56 std::tr1::hash<T> h;
57 return (h(data));
58 }
59
60 CC_END()
61
62 // Used own implementation.
63 #else
64
65 CC_BEGIN()
66
67 template <typename T>
68 std::size_t hash(T const& data) {
69 std::size_t res(14695981039346656037ULL);
70 for (typename T::const_iterator it(data.begin()), end(data.end()); it != end;
71 ++it) {
72 res ^= static_cast<std::size_t>(*it);
73 res *= static_cast<std::size_t>(1099511628211ULL);
74 }
75 return (res);
76 }
77
78 template <>
79 inline std::size_t hash<bool>(bool val) {
80 return (static_cast<std::size_t>(val));
81 }
82
83 template <>
84 inline std::size_t hash<char>(char val) {
85 return (static_cast<std::size_t>(val));
86 }
87
88 template <>
89 inline std::size_t hash<int>(int val) {
90 return (static_cast<std::size_t>(val));
91 }
92
93 template <>
94 inline std::size_t hash<long long>(long long val) {
95 return (static_cast<std::size_t>(val));
96 }
97
98 template <>
99 inline std::size_t hash<long>(long val) {
100 return (static_cast<std::size_t>(val));
101 }
102
103 template <>
104 inline std::size_t hash<short>(short val) {
105 return (static_cast<std::size_t>(val));
106 }
107
108 template <>
109 inline std::size_t hash<unsigned char>(unsigned char val) {
110 return (static_cast<std::size_t>(val));
111 }
112
113 template <>
114 inline std::size_t hash<unsigned int>(unsigned int val) {
115 return (static_cast<std::size_t>(val));
116 }
117
118 template <>
119 inline std::size_t hash<unsigned long long>(unsigned long long val) {
120 return (static_cast<std::size_t>(val));
121 }
122
123 template <>
124 inline std::size_t hash<unsigned long>(unsigned long val) {
125 return (static_cast<std::size_t>(val));
126 }
127
128 template <>
129 inline std::size_t hash<unsigned short>(unsigned short val) {
130 return (static_cast<std::size_t>(val));
131 }
132
133 CC_END()
134
135 #endif // C++0X, tr1 or std
136
CC_BEGIN()137 CC_BEGIN()
138
139 template <typename T, typename U>
140 std::size_t hash(std::pair<T, U> const& data) {
141 std::size_t id(hash(data.first));
142 return (hash(data.second) + 0x9e3779b9 + (id << 6) + (id >> 2));
143 }
144
145 template <typename T>
hash(T begin,T end)146 std::size_t hash(T begin, T end) {
147 std::size_t res(0);
148 while (begin != end) {
149 res ^= hash(*begin) + 0x9e3779b9 + (res << 6) + (res >> 2);
150 ++begin;
151 }
152 return (res);
153 }
154
155 template <typename T>
hash_combine(std::size_t & seed,T const & data)156 std::size_t hash_combine(std::size_t& seed, T const& data) {
157 seed ^= hash(data) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
158 return (seed);
159 }
160
161 template <typename T>
hash_combine(std::size_t & seed,T begin,T end)162 std::size_t hash_combine(std::size_t& seed, T begin, T end) {
163 seed ^= hash(begin, end) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
164 return (seed);
165 }
166
167 CC_END()
168
169 #endif // !CC_HASH_HH
170