Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ikod committed Nov 2, 2019
0 parents commit 0c5c3ed
Show file tree
Hide file tree
Showing 8 changed files with 2,293 additions and 0 deletions.
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.dub
docs.json
__dummy.html
docs/
/containers
containers.so
containers.dylib
containers.dll
containers.a
containers.lib
containers-test-*
*.exe
*.o
*.obj
*.lst
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# ikod-containers
30 changes: 30 additions & 0 deletions dub.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"authors": [
"Igor Khasilev"
],
"copyright": "Copyright © 2019, Igor Khasilev",
"dependencies": {
"unit-threaded": "~>0.10.4",
"automem": "~>0"
},
"description": "containers library",
"license": "BSL-1",
"name": "ikod-containers",
"configurations": [
{
"name": "unittest",
"targetType": "executable",
"versions": ["TestingContainers"],
"preBuildCommands": [
"dub run --compiler=$$DC unit-threaded -c gen_ut_main -- -f bin/ut.d"
],
"dependencies": {
"unit-threaded": "~>0"
},
"excludedSourceFiles": [
"source/app.d"
],
"mainSourceFile": "bin/ut.d"
}
]
}
6 changes: 6 additions & 0 deletions source/app.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import std.stdio;

void main()
{
writeln("Edit source/app.d to start your project.");
}
90 changes: 90 additions & 0 deletions source/ikod/containers/hash.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
module ikod.containers.hash;

import std.traits;

///
/// For classes (and structs with toHash method) we use v.toHash() to compute hash.
/// ===============================================================================
/// toHash method CAN BE @nogc or not. HashMap 'nogc' properties is inherited from this method.
/// toHash method MUST BE @safe or @trusted, as all HashMap code alredy safe.
///
/// See also: https://dlang.org/spec/hash-map.html#using_classes_as_key
/// and https://dlang.org/spec/hash-map.html#using_struct_as_key
///
bool UseToHashMethod(T)() {
return (is(T == class) || (is(T==struct) && __traits(compiles, {
T v = T.init; hash_t h = v.toHash();
})));
}

hash_t hash_function(T)(T v) /* @safe @nogc inherited from toHash method */
if ( UseToHashMethod!T )
{
return v.toHash();
}

hash_t hash_function(T)(in T v) @nogc @trusted
if ( !UseToHashMethod!T )
{
static if ( isNumeric!T ) {
enum m = 0x5bd1e995;
hash_t h = v;
h ^= h >> 13;
h *= m;
h ^= h >> 15;
return h;
}
else static if ( is(T == string) ) {
// // FNV-1a hash
// ulong h = 0xcbf29ce484222325;
// foreach (const ubyte c; cast(ubyte[]) v)
// {
// h ^= c;
// h *= 0x100000001b3;
// }
// return cast(hash_t)h;
import core.internal.hash : bytesHash;
return bytesHash(cast(void*)v.ptr, v.length, 0);
}
else
{
const(ubyte)[] bytes = (cast(const(ubyte)*)&v)[0 .. T.sizeof];
ulong h = 0xcbf29ce484222325;
foreach (const ubyte c; bytes)
{
h ^= c;
h *= 0x100000001b3;
}
return cast(hash_t)h;
}
}

@safe unittest
{
//assert(hash_function("abc") == cast(hash_t)0xe71fa2190541574b);

struct A0 {}
assert(!UseToHashMethod!A0);

struct A1 {
hash_t toHash() const @safe {
return 0;
}
}
assert(UseToHashMethod!A1);

// class with toHash override - will use toHash
class C0 {
override hash_t toHash() const @safe {
return 0;
}
}
assert(UseToHashMethod!C0);
C0 c0 = new C0();
assert(c0.toHash() == 0);

// class without toHash override - use Object.toHash method
class C1 {
}
assert(UseToHashMethod!C1);
}
Loading

0 comments on commit 0c5c3ed

Please sign in to comment.