summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/collections/sets.nim25
-rw-r--r--tests/collections/tsets.nim42
2 files changed, 67 insertions, 0 deletions
diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim
index b2ffbe58d..c0ffcb19c 100644
--- a/lib/pure/collections/sets.nim
+++ b/lib/pure/collections/sets.nim
@@ -41,6 +41,19 @@ type
 
 {.deprecated: [TSet: HashSet].}
 
+template default[T](t: typedesc[T]): T =
+  ## Used by clear methods to get a default value.
+  var v: T
+  v
+
+proc clear*[A](s: var HashSet[A]) = 
+  ## Clears the HashSet back to an empty state, without shrinking
+  ## any of the existing storage. O(n) where n is the size of the hash bucket.
+  s.counter = 0
+  for i in 0..<s.data.len:
+    s.data[i].hcode = 0
+    s.data[i].key   = default(type(s.data[i].key))
+
 # hcode for real keys cannot be zero.  hcode==0 signifies an empty slot.  These
 # two procs retain clarity of that encoding without the space cost of an enum.
 proc isEmpty(hcode: Hash): bool {.inline.} =
@@ -581,6 +594,18 @@ type
 
 {.deprecated: [TOrderedSet: OrderedSet].}
 
+proc clear*[A](s: var OrderedSet[A]) = 
+  ## Clears the OrderedSet back to an empty state, without shrinking
+  ## any of the existing storage. O(n) where n is the size of the hash bucket.
+  s.counter = 0
+  s.first = -1
+  s.last = -1
+  for i in 0..<s.data.len:
+    s.data[i].hcode = 0
+    s.data[i].next = 0
+    s.data[i].key = default(type(s.data[i].key))
+
+
 proc isValid*[A](s: OrderedSet[A]): bool =
   ## Returns `true` if the ordered set has been initialized with `initSet
   ## <#initOrderedSet>`_.
diff --git a/tests/collections/tsets.nim b/tests/collections/tsets.nim
index a5bbe8dbd..6139560bd 100644
--- a/tests/collections/tsets.nim
+++ b/tests/collections/tsets.nim
@@ -34,4 +34,46 @@ block setWithSequences:
   doAssert s.contains(@[1, 2, 3])
   doAssert( not s.contains(@[4, 5, 6]) )
 
+block setClearWorked:
+  var s = initSet[char]() 
+
+  for c in "this is a test":
+    s.incl(c)
+
+  doAssert len(s) == 7
+  clear(s)
+  doAssert len(s) == 0
+
+  s.incl('z')
+  for c in "this is a test":
+    s.incl(c)
+
+  doAssert len(s) == 8
+
+block orderedSetClearWorked:
+  var s = initOrderedSet[char]()
+
+  for c in "eat at joes":
+    s.incl(c)
+
+  var r = ""
+
+  for c in items(s):
+    add(r, c)
+
+  doAssert r == "eat jos"
+  clear(s)
+
+  s.incl('z')
+  for c in "eat at joes":
+    s.incl(c)
+
+  r = "" 
+  for c in items(s):
+    add(r, c)
+
+  doAssert r == "zeat jos"
+
+
+