/usr/lib/gcc/x86_64-linux-gnu/5/include/d/rt/util/hash.d is in libphobos-5-dev 5.5.0-12ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 104 105 106 107 108 109 | /**
* This module contains the default hash implementation.
*
* Copyright: Copyright Sean Kelly 2009 - 2009.
* License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Sean Kelly
*/
/* Copyright Sean Kelly 2009 - 2009.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
module rt.util.hash;
version( X86 )
version = AnyX86;
version( X86_64 )
version = AnyX86;
version( AnyX86 )
version = HasUnalignedOps;
@trusted pure nothrow
size_t hashOf( const (void)* buf, size_t len, size_t seed = 0 )
{
/*
* This is Paul Hsieh's SuperFastHash algorithm, described here:
* http://www.azillionmonkeys.com/qed/hash.html
* It is protected by the following open source license:
* http://www.azillionmonkeys.com/qed/weblicense.html
*/
static uint get16bits( const (ubyte)* x ) pure nothrow
{
// CTFE doesn't support casting ubyte* -> ushort*, so revert to
// per-byte access when in CTFE.
version( HasUnalignedOps )
{
if (!__ctfe)
return *cast(ushort*) x;
}
return ((cast(uint) x[1]) << 8) + (cast(uint) x[0]);
}
// NOTE: SuperFastHash normally starts with a zero hash value. The seed
// value was incorporated to allow chaining.
auto data = cast(const (ubyte)*) buf;
auto hash = seed;
int rem;
if( len <= 0 || data is null )
return 0;
rem = len & 3;
len >>= 2;
for( ; len > 0; len-- )
{
hash += get16bits( data );
auto tmp = (get16bits( data + 2 ) << 11) ^ hash;
hash = (hash << 16) ^ tmp;
data += 2 * ushort.sizeof;
hash += hash >> 11;
}
switch( rem )
{
case 3: hash += get16bits( data );
hash ^= hash << 16;
hash ^= data[ushort.sizeof] << 18;
hash += hash >> 11;
break;
case 2: hash += get16bits( data );
hash ^= hash << 11;
hash += hash >> 17;
break;
case 1: hash += *data;
hash ^= hash << 10;
hash += hash >> 1;
break;
default:
break;
}
/* Force "avalanching" of final 127 bits */
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
}
// Check that hashOf works with CTFE
unittest
{
size_t ctfeHash(string x)
{
return hashOf(x.ptr, x.length);
}
enum test_str = "Sample string";
enum size_t hashVal = ctfeHash(test_str);
assert(hashVal == hashOf(test_str.ptr, test_str.length));
}
|