summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/collections/sets.nim7
-rw-r--r--tests/collections/tsets.nim56
2 files changed, 57 insertions, 6 deletions
diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim
index 900f281e9..94bdbb860 100644
--- a/lib/pure/collections/sets.nim
+++ b/lib/pure/collections/sets.nim
@@ -18,7 +18,7 @@
 ## that ``=`` performs a copy of the set.
 
 import
-  hashes, math
+  hashes, math, algorithm
 
 {.pragma: myShallow.}
 when not defined(nimhygiene):
@@ -123,8 +123,11 @@ iterator items*[A](s: HashSet[A]): A =
 proc hash*[A](s: HashSet[A]): Hash =
   ## hashing of HashSet
   assert s.isValid, "The set needs to be initialized."
+  var hcs: seq[Hash]
   for h in 0..high(s.data):
-    result = result !& s.data[h].hcode
+    hcs.add(s.data[h].hcode)
+  for hc in sorted(hcs, cmp[int]):
+    result = result !& hc
   result = !$result
 
 const
diff --git a/tests/collections/tsets.nim b/tests/collections/tsets.nim
index 6139560bd..be624ffe8 100644
--- a/tests/collections/tsets.nim
+++ b/tests/collections/tsets.nim
@@ -1,4 +1,6 @@
 import sets
+import hashes
+import algorithm
 
 block setEquality:
   var
@@ -35,7 +37,7 @@ block setWithSequences:
   doAssert( not s.contains(@[4, 5, 6]) )
 
 block setClearWorked:
-  var s = initSet[char]() 
+  var s = initSet[char]()
 
   for c in "this is a test":
     s.incl(c)
@@ -68,12 +70,58 @@ block orderedSetClearWorked:
   for c in "eat at joes":
     s.incl(c)
 
-  r = "" 
+  r = ""
   for c in items(s):
     add(r, c)
 
   doAssert r == "zeat jos"
 
+block hashForHashedSet:
+  let
+    seq1 = "This is the test."
+    seq2 = "the test is This."
+    s1 = seq1.toSet()
+    s2 = seq2.toSet()
+  var hashSeq: seq[Hash] = @[]
+  doAssert s1 == s2
+  doAssert hash(s1) == hash(s2)
+  for c in seq1:
+    if (not (hash(c) in hashSeq)):
+      hashSeq.add(hash(c))
+  doAssert hash(s1) == hash(sorted(hashSeq, cmp[Hash]))
+
+block hashForOrderdSet:
+  let
+    str = "This is the test."
+    rstr = str.reversed
 
-
-
+  var
+    s1 = initOrderedSet[char]()
+    s2 = initOrderedSet[char]()
+    r = initOrderedSet[char]()
+    expected: Hash
+    added: seq[char] = @[]
+    reversed: Hash
+    radded: seq[char] = @[]
+
+  expected = 0
+  for c in str:
+    if (not (c in added)):
+      expected = expected !& hash(c)
+      added.add(c)
+    s1.incl(c)
+    s2.incl(c)
+  expected = !$expected
+  doAssert hash(s1) == expected
+  doAssert hash(s1) == hash(s2)
+  doAssert hash(s1) != hash(r)
+
+  reversed = 0
+  for c in rstr:
+    if (not (c in radded)):
+      reversed = reversed !& hash(c)
+      radded.add(c)
+    r.incl(c)
+  reversed = !$reversed
+  doAssert hash(r) == reversed
+  doAssert hash(s1) != reversed