summaryrefslogtreecommitdiff
path: root/src/jit/jitstd/hash.h
blob: 18db74fc9f5a5371985a7d58232e41cde036cbb9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.



#pragma once

#include "type_traits.h"
#include <stdio.h>

namespace jitstd
{
template<typename Type>
class hash
{
public:
    size_t operator()(const Type& val) const
    {
        div_t qrem = ::div((int)(size_t) val, 127773);
        qrem.rem = 16807 * qrem.rem - 2836 * qrem.quot;
        if (qrem.rem < 0)
        {
            qrem.rem += 2147483647;
        }
        return ((size_t) qrem.rem);
    }
};

template<>
class hash<int>
{
public:
    size_t operator()(const int& val) const
    {
        return val;
    }
};

template<>
class hash<unsigned __int64>
{
private:
    typedef unsigned __int64 Type;

public:
    size_t operator()(const Type& val) const
    {
        return (hash<int>()((int)(val & 0xffffffffUL)) ^ hash<int>()((int)(val >> 32)));
    }
};

template<>
class hash<__int64>
{
private:
    typedef __int64 Type;

public:
    size_t operator()(const Type& val) const
    {
        return (hash<unsigned __int64>()((unsigned __int64) val));
    }
};

template<typename Type>
class hash<Type*>
{
private:
    typedef typename conditional<sizeof (Type*) <= sizeof (int), int, __int64>::type TInteger;
public:
    size_t operator()(const Type* val) const
    {
        return (hash<TInteger>()((TInteger) val));
    }
};

template<>
class hash<float>
{
private:
    typedef float Type;
public:
    size_t operator()(const Type& val) const
    {
        unsigned long bits = *(unsigned long*) &val;
        return (hash<unsigned long>()(bits == 0x80000000 ? 0 : bits));
    }
};

template<>
class hash<double>
{
public:
    typedef double Type;
    size_t operator()(const Type& val) const
    {
        unsigned __int64 bits = *(unsigned __int64*)&val;
        return (hash<unsigned __int64>()((bits & (((unsigned __int64) -1) >> 1)) == 0 ? 0 : bits));
    }
};

}