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