diff --git a/lib/std/hash/fnv32a.c3 b/lib/std/hash/fnv32a.c3 index dbc517fc2..ec20d3e38 100644 --- a/lib/std/hash/fnv32a.c3 +++ b/lib/std/hash/fnv32a.c3 @@ -8,7 +8,7 @@ distinct Fnv32a = uint; const FNV32A_START @private = 0x811c9dc5; const FNV32A_MUL @private = 0x01000193; -macro void @update(uint* &h, char x) @private => *h = (*h * FNV32A_MUL) ^ x; +macro void @update(&h, char x) @private => *h = (*h ^ ($typeof(*h))x) * FNV32A_MUL; fn void Fnv32a.init(&self) { @@ -17,17 +17,17 @@ fn void Fnv32a.init(&self) fn void Fnv32a.update(&self, char[] data) { - uint h = (uint)*self; + Fnv32a h = *self; foreach (char x : data) { @update(h, x); } - *self = (Fnv32a)h; + *self = h; } macro void Fnv32a.update_char(&self, char c) { - @update(*self, x); + @update(*self, c); } fn uint encode(char[] data) @@ -38,4 +38,4 @@ fn uint encode(char[] data) @update(h, x); } return h; -} \ No newline at end of file +} diff --git a/lib/std/hash/fnv64a.c3 b/lib/std/hash/fnv64a.c3 index 7c8093312..62da516e8 100644 --- a/lib/std/hash/fnv64a.c3 +++ b/lib/std/hash/fnv64a.c3 @@ -8,7 +8,7 @@ distinct Fnv64a = ulong; const FNV64A_START @private = 0xcbf29ce484222325; const FNV64A_MUL @private = 0x00000100000001b3; -macro void @update(ulong* &h, char x) @private => *h = (*h * FNV64A_MUL) ^ x; +macro void @update(&h, char x) @private => *h = (*h ^ ($typeof(*h))x) * FNV64A_MUL; fn void Fnv64a.init(&self) { @@ -17,17 +17,17 @@ fn void Fnv64a.init(&self) fn void Fnv64a.update(&self, char[] data) { - ulong h = (ulong)*self; + Fnv64a h = *self; foreach (char x : data) { @update(h, x); } - *self = (Fnv64a)h; + *self = h; } macro void Fnv64a.update_char(&self, char c) { - @update(*self, x); + @update(*self, c); } fn ulong encode(char[] data) @@ -38,4 +38,4 @@ fn ulong encode(char[] data) @update(h, x); } return h; -} \ No newline at end of file +} diff --git a/test/unit/stdlib/hash/fnv32a.c3 b/test/unit/stdlib/hash/fnv32a.c3 new file mode 100644 index 000000000..553a93a0e --- /dev/null +++ b/test/unit/stdlib/hash/fnv32a.c3 @@ -0,0 +1,24 @@ +module std::hash::fnv32a_test @test; +import std::hash::fnv32a; + +fn void test_fnv32a() +{ + Fnv32a hash; + + char[] input = "Hello world"; + uint want = 0x594d29c7; + + // update + hash.init(); + hash.update(input); + assert ((uint)hash == want, "got: %d, want: %d", hash, want); + + // update_char + hash.init(); + foreach (c : input) hash.update_char(c); + assert ((uint)hash == want, "got: %d, want: %d", hash, want); + + // encode + uint encoded = fnv32a::encode(input); + assert (encoded == want, "got: %d, want: %d", encoded, want); +} diff --git a/test/unit/stdlib/hash/fnv64a.c3 b/test/unit/stdlib/hash/fnv64a.c3 new file mode 100644 index 000000000..60dcd910c --- /dev/null +++ b/test/unit/stdlib/hash/fnv64a.c3 @@ -0,0 +1,24 @@ +module std::hash::fnv64a_test @test; +import std::hash::fnv64a; + +fn void test_fnv64a() +{ + Fnv64a hash; + + char[] input = "Hello world"; + ulong want = 0x2713f785a33764c7; + + // update + hash.init(); + hash.update(input); + assert ((ulong)hash == want, "got: %d, want: %d", hash, want); + + // update_char + hash.init(); + foreach (c : input) hash.update_char(c); + assert ((ulong)hash == want, "got: %d, want: %d", hash, want); + + // encode + ulong encoded = fnv64a::encode(input); + assert (encoded == want, "got: %d, want: %d", encoded, want); +}