Embedded Template Library 1.0
Loading...
Searching...
No Matches
hash.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2014 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_HASH_INCLUDED
32#define ETL_HASH_INCLUDED
33
34#include "platform.h"
35
36#if ETL_USING_8BIT_TYPES
37
38// The default hash calculation.
39#include "fnv_1.h"
40#include "type_traits.h"
41#include "static_assert.h"
42#include "math.h"
43
44#include <stdint.h>
45#include <stdlib.h>
46
49
51
52namespace etl
53{
54 namespace private_hash
55 {
56 //*************************************************************************
59 //*************************************************************************
60 template <typename T>
61 typename enable_if<sizeof(T) == sizeof(uint16_t), size_t>::type
62 generic_hash(const uint8_t* begin, const uint8_t* end)
63 {
64 uint32_t h = fnv_1a_32(begin, end);
65
66 return static_cast<size_t>(h ^ (h >> 16U));
67 }
68
69 //*************************************************************************
72 //*************************************************************************
73 template <typename T>
74 typename enable_if<sizeof(T) == sizeof(uint32_t), size_t>::type
75 generic_hash(const uint8_t* begin, const uint8_t* end)
76 {
77 return fnv_1a_32(begin, end);
78 }
79
80#if ETL_USING_64BIT_TYPES
81 //*************************************************************************
84 //*************************************************************************
85 template <typename T>
86 typename enable_if<sizeof(T) == sizeof(uint64_t), size_t>::type
87 generic_hash(const uint8_t* begin, const uint8_t* end)
88 {
89 return fnv_1a_64(begin, end);
90 }
91#endif
92
93 //*************************************************************************
95 //*************************************************************************
96 template<typename T, bool IsEnum=false>
97 struct hash_base
98 {
99 private:
100 hash_base(); // Can't default construct
101 hash_base(const hash_base& other); // Can't copy construct
102 hash_base& operator=(const hash_base& other); // Can't copy assign
103
104#if ETL_USING_CPP11
105 hash_base(hash_base&& other); // Can't move construct
106 hash_base& operator=(hash_base&& other); // Can't move assign
107#endif
108 };
109
110 // Specialization for enums depends on definitions for integers, so it comes later
111 }
112
113#if ETL_USING_CPP11
114 //***************************************************************************
117 //***************************************************************************
118 template <typename T>
119 struct hash : private_hash::hash_base<T, etl::is_enum<T>::value>{};
120#else
121 //***************************************************************************
124 //***************************************************************************
125 template <typename T> struct hash;
126#endif
127
128 //***************************************************************************
131 //***************************************************************************
132 template <>
133 struct hash <bool>
134 {
135 ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(bool), "size_t smaller than type");
136
137 size_t operator ()(bool v) const
138 {
139 return static_cast<size_t>(v);
140 }
141 };
142
143 //***************************************************************************
146 //***************************************************************************
147 template <>
148 struct hash<char>
149 {
150 ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(char), "size_t smaller than type");
151
152 size_t operator ()(char v) const
153 {
154 return static_cast<size_t>(v);
155 }
156 };
157
158 //***************************************************************************
161 //***************************************************************************
162 template<> struct
163 hash<signed char>
164 {
165 ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(signed char), "size_t smaller than type");
166
167 size_t operator ()(signed char v) const
168 {
169 return static_cast<size_t>(v);
170 }
171 };
172
173 //***************************************************************************
176 //***************************************************************************
177 template<>
178 struct hash<unsigned char>
179 {
180 ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned char), "size_t smaller than type");
181
182 size_t operator ()(unsigned char v) const
183 {
184 return static_cast<size_t>(v);
185 }
186 };
187
188 //***************************************************************************
191 //***************************************************************************
192 template<>
193 struct hash<wchar_t>
194 {
195 size_t operator ()(wchar_t v) const
196 {
197 // If it's the same size as a size_t.
198 if ETL_IF_CONSTEXPR(sizeof(size_t) >= sizeof(v))
199 {
200 return static_cast<size_t>(v);
201 }
202 else
203 {
204 uint8_t* p = reinterpret_cast<uint8_t*>(&v);
205 return private_hash::generic_hash<size_t>(p, p + sizeof(v));
206 }
207 }
208 };
209
210 //***************************************************************************
213 //***************************************************************************
214 template<>
215 struct hash<short>
216 {
217 size_t operator ()(short v) const
218 {
219 // If it's the same size as a size_t.
220 if ETL_IF_CONSTEXPR(sizeof(size_t) >= sizeof(v))
221 {
222 return static_cast<size_t>(v);
223 }
224 else
225 {
226 uint8_t* p = reinterpret_cast<uint8_t*>(&v);
227 return private_hash::generic_hash<size_t>(p, p + sizeof(v));
228 }
229 }
230 };
231
232 //***************************************************************************
235 //***************************************************************************
236 template<>
237 struct hash<unsigned short>
238 {
239 size_t operator ()(unsigned short v) const
240 {
241 // If it's the same size as a size_t.
242 if ETL_IF_CONSTEXPR(sizeof(size_t) >= sizeof(v))
243 {
244 return static_cast<size_t>(v);
245 }
246 else
247 {
248 uint8_t* p = reinterpret_cast<uint8_t*>(&v);
249 return private_hash::generic_hash<size_t>(p, p + sizeof(v));
250 }
251 }
252 };
253
254 //***************************************************************************
257 //***************************************************************************
258 template<>
259 struct hash<int>
260 {
261 size_t operator ()(int v) const
262 {
263 // If it's the same size as a size_t.
264 if ETL_IF_CONSTEXPR(sizeof(size_t) >= sizeof(v))
265 {
266 return static_cast<size_t>(v);
267 }
268 else
269 {
270 uint8_t* p = reinterpret_cast<uint8_t*>(&v);
271 return private_hash::generic_hash<size_t>(p, p + sizeof(v));
272 }
273 }
274 };
275
276 //***************************************************************************
279 //***************************************************************************
280 template<>
281 struct hash<unsigned int>
282 {
283 size_t operator ()(unsigned int v) const
284 {
285 // If it's the same size as a size_t.
286 if ETL_IF_CONSTEXPR(sizeof(size_t) >= sizeof(v))
287 {
288 return static_cast<size_t>(v);
289 }
290 else
291 {
292 uint8_t* p = reinterpret_cast<uint8_t*>(&v);
293 return private_hash::generic_hash<size_t>(p, p + sizeof(v));
294 }
295 }
296 };
297
298 //***************************************************************************
301 //***************************************************************************
302 template<>
303 struct hash<long>
304 {
305 size_t operator ()(long v) const
306 {
307 // If it's the same size as a size_t.
308 if ETL_IF_CONSTEXPR(sizeof(size_t) >= sizeof(v))
309 {
310 return static_cast<size_t>(v);
311 }
312 else
313 {
314 uint8_t* p = reinterpret_cast<uint8_t*>(&v);
315 return private_hash::generic_hash<size_t>(p, p + sizeof(v));
316 }
317 }
318 };
319
320 //***************************************************************************
323 //***************************************************************************
324 template<>
325 struct hash<long long>
326 {
327 size_t operator ()(long long v) const
328 {
329 // If it's the same size as a size_t.
330 if ETL_IF_CONSTEXPR(sizeof(size_t) >= sizeof(v))
331 {
332 return static_cast<size_t>(v);
333 }
334 else
335 {
336 uint8_t* p = reinterpret_cast<uint8_t*>(&v);
337 return private_hash::generic_hash<size_t>(p, p + sizeof(v));
338 }
339 }
340 };
341
342 //***************************************************************************
345 //***************************************************************************
346 template<>
347 struct hash<unsigned long>
348 {
349 size_t operator ()(unsigned long v) const
350 {
351 // If it's the same size as a size_t.
352 if ETL_IF_CONSTEXPR(sizeof(size_t) >= sizeof(v))
353 {
354 return static_cast<size_t>(v);
355 }
356 else
357 {
358 uint8_t* p = reinterpret_cast<uint8_t*>(&v);
359 return private_hash::generic_hash<size_t>(p, p + sizeof(v));
360 }
361 }
362 };
363
364 //***************************************************************************
367 //***************************************************************************
368 template<>
369 struct hash<unsigned long long>
370 {
371 size_t operator ()(unsigned long long v) const
372 {
373 // If it's the same size as a size_t.
374 if ETL_IF_CONSTEXPR(sizeof(size_t) >= sizeof(v))
375 {
376 return static_cast<size_t>(v);
377 }
378 else
379 {
380 uint8_t* p = reinterpret_cast<uint8_t*>(&v);
381 return private_hash::generic_hash<size_t>(p, p + sizeof(v));
382 }
383 }
384 };
385
386 //***************************************************************************
389 //***************************************************************************
390 template<>
391 struct hash<float>
392 {
393 size_t operator ()(float v) const
394 {
395 // If it's the same size as a size_t.
396 if ETL_IF_CONSTEXPR(sizeof(size_t) == sizeof(v))
397 {
398 union
399 {
400 size_t s;
401 float v;
402 } u;
403
404 if (etl::is_zero(v))
405 { // -0.0 and 0.0 are represented differently at bit level
406 v = 0.0f;
407 }
408 u.v = v;
409
410 return u.s;
411 }
412 else
413 {
414 uint8_t* p = reinterpret_cast<uint8_t*>(&v);
415 return private_hash::generic_hash<size_t>(p, p + sizeof(v));
416 }
417 }
418 };
419
420 //***************************************************************************
423 //***************************************************************************
424 template<>
425 struct hash<double>
426 {
427 size_t operator ()(double v) const
428 {
429 // If it's the same size as a size_t.
430 if ETL_IF_CONSTEXPR(sizeof(size_t) == sizeof(v))
431 {
432 union
433 {
434 size_t s;
435 double v;
436 } u;
437
438 if (etl::is_zero(v))
439 { // -0.0 and 0.0 are represented differently at bit level
440 v = 0.0;
441 }
442 u.v = v;
443
444 return u.s;
445 }
446 else
447 {
448 uint8_t* p = reinterpret_cast<uint8_t*>(&v);
449 return private_hash::generic_hash<size_t>(p, p + sizeof(v));
450 }
451 }
452 };
453
454 //***************************************************************************
457 //***************************************************************************
458 template<>
459 struct hash<long double>
460 {
461 size_t operator ()(long double v) const
462 {
463 // If it's the same size as a size_t.
464 if ETL_IF_CONSTEXPR(sizeof(size_t) == sizeof(v))
465 {
466 union
467 {
468 size_t s;
469 long double v;
470 } u;
471
472 if (etl::is_zero(v))
473 { // -0.0 and 0.0 are represented differently at bit level
474 v = 0.0L;
475 }
476 u.v = v;
477
478 return u.s;
479 }
480 else
481 {
482 uint8_t* p = reinterpret_cast<uint8_t*>(&v);
483 return private_hash::generic_hash<size_t>(p, p + sizeof(v));
484 }
485 }
486 };
487
488 //***************************************************************************
491 //***************************************************************************
492 template <typename T>
493 struct hash<T*>
494 {
495 size_t operator ()(const T* v) const
496 {
497 // If it's the same size as a size_t.
498 if (sizeof(size_t) == sizeof(T*))
499 {
500 union
501 {
502 size_t s;
503 const T* v;
504 } u;
505
506 u.v = v;
507
508 return u.s;
509 }
510 else
511 {
512 uint8_t* p = reinterpret_cast<uint8_t*>(&v);
513 return private_hash::generic_hash<size_t>(p, p + sizeof(v));
514 }
515 }
516 };
517
518 namespace private_hash
519 {
520 //*************************************************************************
522 //*************************************************************************
523 template<typename T>
524 struct hash_base<T, true>
525 {
526 size_t operator()(T v) const
527 {
528 if (sizeof(size_t) >= sizeof(T))
529 {
530 return static_cast<size_t>(v);
531 }
532 else
533 {
534 return ::etl::hash<unsigned long long>()(static_cast<unsigned long long>(v));
535 }
536 }
537 };
538 }
539}
540
542
543#endif // ETL_USING_8BIT_TYPES
544
545#endif
bitset_ext
Definition absolute.h:38
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition iterator.h:962
ETL_CONSTEXPR TContainer::iterator end(TContainer &container)
Definition iterator.h:992
ETL_CONSTEXPR pair()
Default constructor.
Definition utility.h:176