source: mainline/uspace/lib/cpp/include/internal/functional/hash.hpp@ 0e5e8bf9

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

cpp: moved hash out of functional.hpp

  • Property mode set to 100644
File size: 7.2 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
32namespace std
33{
34 /**
35 * 20.9.13, hash function primary template:
36 */
37
38 namespace aux
39 {
40 template<class T>
41 union converter
42 {
43 T value;
44 uint64_t converted;
45 };
46
47 template<class T>
48 T hash_(uint64_t x) noexcept
49 {
50 /**
51 * Note: std::hash is used for indexing in
52 * unordered containers, not for cryptography.
53 * Because of this, we decided to simply convert
54 * the value to uin64_t, which will help us
55 * with testing (since in order to create
56 * a collision in a multiset or multimap
57 * we simply need 2 values that congruent
58 * by the size of the table.
59 */
60 return static_cast<T>(x);
61 }
62
63 template<class T>
64 size_t hash(T x) noexcept
65 {
66 static_assert(is_arithmetic_v<T> || is_pointer_v<T>,
67 "invalid type passed to aux::hash");
68
69 converter<T> conv;
70 conv.value = x;
71
72 return hash_<size_t>(conv.converted);
73 }
74 }
75
76 template<class T>
77 struct hash
78 { /* DUMMY BODY */ };
79
80 template<>
81 struct hash<bool>
82 {
83 size_t operator()(bool x) const noexcept
84 {
85 return aux::hash(x);
86 }
87
88 using argument_type = bool;
89 using result_type = size_t;
90 };
91
92 template<>
93 struct hash<char>
94 {
95 size_t operator()(char x) const noexcept
96 {
97 return aux::hash(x);
98 }
99
100 using argument_type = char;
101 using result_type = size_t;
102 };
103
104 template<>
105 struct hash<signed char>
106 {
107 size_t operator()(signed char x) const noexcept
108 {
109 return aux::hash(x);
110 }
111
112 using argument_type = signed char;
113 using result_type = size_t;
114 };
115
116 template<>
117 struct hash<unsigned char>
118 {
119 size_t operator()(unsigned char x) const noexcept
120 {
121 return aux::hash(x);
122 }
123
124 using argument_type = unsigned char;
125 using result_type = size_t;
126 };
127
128 template<>
129 struct hash<char16_t>
130 {
131 size_t operator()(char16_t x) const noexcept
132 {
133 return aux::hash(x);
134 }
135
136 using argument_type = char16_t;
137 using result_type = size_t;
138 };
139
140 template<>
141 struct hash<char32_t>
142 {
143 size_t operator()(char32_t x) const noexcept
144 {
145 return aux::hash(x);
146 }
147
148 using argument_type = char32_t;
149 using result_type = size_t;
150 };
151
152 template<>
153 struct hash<wchar_t>
154 {
155 size_t operator()(wchar_t x) const noexcept
156 {
157 return aux::hash(x);
158 }
159
160 using argument_type = wchar_t;
161 using result_type = size_t;
162 };
163
164 template<>
165 struct hash<short>
166 {
167 size_t operator()(short x) const noexcept
168 {
169 return aux::hash(x);
170 }
171
172 using argument_type = short;
173 using result_type = size_t;
174 };
175
176 template<>
177 struct hash<unsigned short>
178 {
179 size_t operator()(unsigned short x) const noexcept
180 {
181 return aux::hash(x);
182 }
183
184 using argument_type = unsigned short;
185 using result_type = size_t;
186 };
187
188 template<>
189 struct hash<int>
190 {
191 size_t operator()(int x) const noexcept
192 {
193 return aux::hash(x);
194 }
195
196 using argument_type = int;
197 using result_type = size_t;
198 };
199
200 template<>
201 struct hash<unsigned int>
202 {
203 size_t operator()(unsigned int x) const noexcept
204 {
205 return aux::hash(x);
206 }
207
208 using argument_type = unsigned int;
209 using result_type = size_t;
210 };
211
212 template<>
213 struct hash<long>
214 {
215 size_t operator()(long x) const noexcept
216 {
217 return aux::hash(x);
218 }
219
220 using argument_type = long;
221 using result_type = size_t;
222 };
223
224 template<>
225 struct hash<long long>
226 {
227 size_t operator()(long long x) const noexcept
228 {
229 return aux::hash(x);
230 }
231
232 using argument_type = long long;
233 using result_type = size_t;
234 };
235
236 template<>
237 struct hash<unsigned long>
238 {
239 size_t operator()(unsigned long x) const noexcept
240 {
241 return aux::hash(x);
242 }
243
244 using argument_type = unsigned long;
245 using result_type = size_t;
246 };
247
248 template<>
249 struct hash<unsigned long long>
250 {
251 size_t operator()(unsigned long long x) const noexcept
252 {
253 return aux::hash(x);
254 }
255
256 using argument_type = unsigned long long;
257 using result_type = size_t;
258 };
259
260 template<>
261 struct hash<float>
262 {
263 size_t operator()(float x) const noexcept
264 {
265 return aux::hash(x);
266 }
267
268 using argument_type = float;
269 using result_type = size_t;
270 };
271
272 template<>
273 struct hash<double>
274 {
275 size_t operator()(double x) const noexcept
276 {
277 return aux::hash(x);
278 }
279
280 using argument_type = double;
281 using result_type = size_t;
282 };
283
284 template<>
285 struct hash<long double>
286 {
287 size_t operator()(long double x) const noexcept
288 {
289 return aux::hash(x);
290 }
291
292 using argument_type = long double;
293 using result_type = size_t;
294 };
295
296 template<class T>
297 struct hash<T*>
298 {
299 size_t operator()(T* x) const noexcept
300 {
301 return aux::hash(x);
302 }
303
304 using argument_type = T*;
305 using result_type = size_t;
306 };
307}
308
309#endif
Note: See TracBrowser for help on using the repository browser.