source: mainline/uspace/lib/cpp/include/internal/functional/hash.hpp@ 8f8f1d1e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8f8f1d1e was 8f8f1d1e, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: removed usage of _v aliases and added forward declarations instead, this avoids possible circular reference

  • Property mode set to 100644
File size: 7.3 KB
Line 
1/*
2 * Copyright (c) 2018 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_INTERNAL_FUNCTIONAL_HASH
30#define LIBCPP_INTERNAL_FUNCTIONAL_HASH
31
32#include <cstdlib>
33
34namespace std
35{
36 template<class>
37 struct is_arithmetic;
38
39 template<class>
40 struct is_pointer;
41
42 /**
43 * 20.9.13, hash function primary template:
44 */
45
46 namespace aux
47 {
48 template<class T>
49 union converter
50 {
51 T value;
52 uint64_t converted;
53 };
54
55 template<class T>
56 T hash_(uint64_t x) noexcept
57 {
58 /**
59 * Note: std::hash is used for indexing in
60 * unordered containers, not for cryptography.
61 * Because of this, we decided to simply convert
62 * the value to uin64_t, which will help us
63 * with testing (since in order to create
64 * a collision in a multiset or multimap
65 * we simply need 2 values that congruent
66 * by the size of the table.
67 */
68 return static_cast<T>(x);
69 }
70
71 template<class T>
72 size_t hash(T x) noexcept
73 {
74 static_assert(is_arithmetic<T>::value || is_pointer<T>::value,
75 "invalid type passed to aux::hash");
76
77 converter<T> conv;
78 conv.value = x;
79
80 return hash_<size_t>(conv.converted);
81 }
82 }
83
84 template<class T>
85 struct hash
86 { /* DUMMY BODY */ };
87
88 template<>
89 struct hash<bool>
90 {
91 size_t operator()(bool x) const noexcept
92 {
93 return aux::hash(x);
94 }
95
96 using argument_type = bool;
97 using result_type = size_t;
98 };
99
100 template<>
101 struct hash<char>
102 {
103 size_t operator()(char x) const noexcept
104 {
105 return aux::hash(x);
106 }
107
108 using argument_type = char;
109 using result_type = size_t;
110 };
111
112 template<>
113 struct hash<signed char>
114 {
115 size_t operator()(signed char x) const noexcept
116 {
117 return aux::hash(x);
118 }
119
120 using argument_type = signed char;
121 using result_type = size_t;
122 };
123
124 template<>
125 struct hash<unsigned char>
126 {
127 size_t operator()(unsigned char x) const noexcept
128 {
129 return aux::hash(x);
130 }
131
132 using argument_type = unsigned char;
133 using result_type = size_t;
134 };
135
136 template<>
137 struct hash<char16_t>
138 {
139 size_t operator()(char16_t x) const noexcept
140 {
141 return aux::hash(x);
142 }
143
144 using argument_type = char16_t;
145 using result_type = size_t;
146 };
147
148 template<>
149 struct hash<char32_t>
150 {
151 size_t operator()(char32_t x) const noexcept
152 {
153 return aux::hash(x);
154 }
155
156 using argument_type = char32_t;
157 using result_type = size_t;
158 };
159
160 template<>
161 struct hash<wchar_t>
162 {
163 size_t operator()(wchar_t x) const noexcept
164 {
165 return aux::hash(x);
166 }
167
168 using argument_type = wchar_t;
169 using result_type = size_t;
170 };
171
172 template<>
173 struct hash<short>
174 {
175 size_t operator()(short x) const noexcept
176 {
177 return aux::hash(x);
178 }
179
180 using argument_type = short;
181 using result_type = size_t;
182 };
183
184 template<>
185 struct hash<unsigned short>
186 {
187 size_t operator()(unsigned short x) const noexcept
188 {
189 return aux::hash(x);
190 }
191
192 using argument_type = unsigned short;
193 using result_type = size_t;
194 };
195
196 template<>
197 struct hash<int>
198 {
199 size_t operator()(int x) const noexcept
200 {
201 return aux::hash(x);
202 }
203
204 using argument_type = int;
205 using result_type = size_t;
206 };
207
208 template<>
209 struct hash<unsigned int>
210 {
211 size_t operator()(unsigned int x) const noexcept
212 {
213 return aux::hash(x);
214 }
215
216 using argument_type = unsigned int;
217 using result_type = size_t;
218 };
219
220 template<>
221 struct hash<long>
222 {
223 size_t operator()(long x) const noexcept
224 {
225 return aux::hash(x);
226 }
227
228 using argument_type = long;
229 using result_type = size_t;
230 };
231
232 template<>
233 struct hash<long long>
234 {
235 size_t operator()(long long x) const noexcept
236 {
237 return aux::hash(x);
238 }
239
240 using argument_type = long long;
241 using result_type = size_t;
242 };
243
244 template<>
245 struct hash<unsigned long>
246 {
247 size_t operator()(unsigned long x) const noexcept
248 {
249 return aux::hash(x);
250 }
251
252 using argument_type = unsigned long;
253 using result_type = size_t;
254 };
255
256 template<>
257 struct hash<unsigned long long>
258 {
259 size_t operator()(unsigned long long x) const noexcept
260 {
261 return aux::hash(x);
262 }
263
264 using argument_type = unsigned long long;
265 using result_type = size_t;
266 };
267
268 template<>
269 struct hash<float>
270 {
271 size_t operator()(float x) const noexcept
272 {
273 return aux::hash(x);
274 }
275
276 using argument_type = float;
277 using result_type = size_t;
278 };
279
280 template<>
281 struct hash<double>
282 {
283 size_t operator()(double x) const noexcept
284 {
285 return aux::hash(x);
286 }
287
288 using argument_type = double;
289 using result_type = size_t;
290 };
291
292 template<>
293 struct hash<long double>
294 {
295 size_t operator()(long double x) const noexcept
296 {
297 return aux::hash(x);
298 }
299
300 using argument_type = long double;
301 using result_type = size_t;
302 };
303
304 template<class T>
305 struct hash<T*>
306 {
307 size_t operator()(T* x) const noexcept
308 {
309 return aux::hash(x);
310 }
311
312 using argument_type = T*;
313 using result_type = size_t;
314 };
315}
316
317#endif
Note: See TracBrowser for help on using the repository browser.