1 | // Licensed to the .NET Foundation under one or more agreements. |
---|---|
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | |
6 | |
7 | #pragma once |
8 | |
9 | #include "type_traits.h" |
10 | #include <stdio.h> |
11 | |
12 | namespace jitstd |
13 | { |
14 | template<typename Type> |
15 | class hash |
16 | { |
17 | public: |
18 | size_t operator()(const Type& val) const |
19 | { |
20 | div_t qrem = ::div((int)(size_t) val, 127773); |
21 | qrem.rem = 16807 * qrem.rem - 2836 * qrem.quot; |
22 | if (qrem.rem < 0) |
23 | { |
24 | qrem.rem += 2147483647; |
25 | } |
26 | return ((size_t) qrem.rem); |
27 | } |
28 | }; |
29 | |
30 | template<> |
31 | class hash<int> |
32 | { |
33 | public: |
34 | size_t operator()(const int& val) const |
35 | { |
36 | return val; |
37 | } |
38 | }; |
39 | |
40 | template<> |
41 | class hash<unsigned __int64> |
42 | { |
43 | private: |
44 | typedef unsigned __int64 Type; |
45 | |
46 | public: |
47 | size_t operator()(const Type& val) const |
48 | { |
49 | return (hash<int>()((int)(val & 0xffffffffUL)) ^ hash<int>()((int)(val >> 32))); |
50 | } |
51 | }; |
52 | |
53 | template<> |
54 | class hash<__int64> |
55 | { |
56 | private: |
57 | typedef __int64 Type; |
58 | |
59 | public: |
60 | size_t operator()(const Type& val) const |
61 | { |
62 | return (hash<unsigned __int64>()((unsigned __int64) val)); |
63 | } |
64 | }; |
65 | |
66 | template<typename Type> |
67 | class hash<Type*> |
68 | { |
69 | private: |
70 | typedef typename conditional<sizeof (Type*) <= sizeof (int), int, __int64>::type TInteger; |
71 | public: |
72 | size_t operator()(const Type* val) const |
73 | { |
74 | return (hash<TInteger>()((TInteger) val)); |
75 | } |
76 | }; |
77 | |
78 | template<> |
79 | class hash<float> |
80 | { |
81 | private: |
82 | typedef float Type; |
83 | public: |
84 | size_t operator()(const Type& val) const |
85 | { |
86 | unsigned long bits = *(unsigned long*) &val; |
87 | return (hash<unsigned long>()(bits == 0x80000000 ? 0 : bits)); |
88 | } |
89 | }; |
90 | |
91 | template<> |
92 | class hash<double> |
93 | { |
94 | public: |
95 | typedef double Type; |
96 | size_t operator()(const Type& val) const |
97 | { |
98 | unsigned __int64 bits = *(unsigned __int64*)&val; |
99 | return (hash<unsigned __int64>()((bits & (((unsigned __int64) -1) >> 1)) == 0 ? 0 : bits)); |
100 | } |
101 | }; |
102 | |
103 | } |
104 |