summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/collections/tables.nim41
-rw-r--r--tests/collections/ttables.nim33
2 files changed, 70 insertions, 4 deletions
diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim
index 778ea5ca3..fe75f9a58 100644
--- a/lib/pure/collections/tables.nim
+++ b/lib/pure/collections/tables.nim
@@ -338,7 +338,7 @@ proc hasKey*[A, B](t: TableRef[A, B], key: A): bool =
   ## returns true iff `key` is in the table `t`.
   result = t[].hasKey(key)
 
-template equalsImpl(t) =
+template equalsImpl(s, t: typed): typed =
   if s.counter == t.counter:
     # different insertion orders mean different 'data' seqs, so we have
     # to use the slow route here:
@@ -348,7 +348,9 @@ template equalsImpl(t) =
     return true
 
 proc `==`*[A, B](s, t: Table[A, B]): bool =
-  equalsImpl(t)
+  ## The `==` operator for hash tables. Returns ``true`` iff the content of both
+  ## tables contains the same key-value pairs. Insert order does not matter.
+  equalsImpl(s, t)
 
 proc indexBy*[A, B, C](collection: A, index: proc(x: B): C): Table[C, B] =
   ## Index the collection with the proc provided.
@@ -436,9 +438,12 @@ proc `$`*[A, B](t: TableRef[A, B]): string =
   dollarImpl()
 
 proc `==`*[A, B](s, t: TableRef[A, B]): bool =
+  ## The `==` operator for hash tables. Returns ``true`` iff either both tables 
+  ## are ``nil`` or none is ``nil`` and the content of both tables contains the
+  ## same key-value pairs. Insert order does not matter.
   if isNil(s): result = isNil(t)
   elif isNil(t): result = false
-  else: equalsImpl(t[])
+  else: equalsImpl(s[], t[])
 
 proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): TableRef[C, B] =
   ## Index the collection with the proc provided.
@@ -464,12 +469,16 @@ proc len*[A, B](t: OrderedTable[A, B]): int {.inline.} =
   ## returns the number of keys in `t`.
   result = t.counter
 
-proc clear*[A, B](t: var OrderedTable[A, B] | OrderedTableRef[A, B]) =
+proc clear*[A, B](t: var OrderedTable[A, B]) =
   ## Resets the table so that it is empty.
   clearImpl()
   t.first = -1
   t.last = -1
 
+proc clear*[A, B](t: var OrderedTableRef[A, B]) =
+  ## Resets the table so that is is empty.
+  clear(t[])
+
 template forAllOrderedPairs(yieldStmt: untyped) {.oldimmediate, dirty.} =
   var h = t.first
   while h >= 0:
@@ -606,6 +615,15 @@ proc `$`*[A, B](t: OrderedTable[A, B]): string =
   ## The `$` operator for ordered hash tables.
   dollarImpl()
 
+proc `==`*[A, B](s, t: OrderedTable[A, B]): bool =
+  ## The `==` operator for ordered hash tables. Both the content and the order
+  ## must be equal for this to return ``true``.
+  if s.counter == t.counter:
+    forAllOrderedPairs:
+      if s.data[h] != t.data[h]: return false
+    result = true
+  else: result = false
+
 proc sort*[A, B](t: var OrderedTable[A, B],
                  cmp: proc (x,y: (A, B)): int) =
   ## sorts `t` according to `cmp`. This modifies the internal list
@@ -749,6 +767,11 @@ proc `$`*[A, B](t: OrderedTableRef[A, B]): string =
   ## The `$` operator for ordered hash tables.
   dollarImpl()
 
+proc `==`*[A, B](s, t: OrderedTableRef[A, B]): bool =
+  ## The `==` operator for ordered hash tables. Both the content and the order
+  ## must be equal for this to return ``true``.
+  result = s[] == t[]
+
 proc sort*[A, B](t: OrderedTableRef[A, B],
                  cmp: proc (x,y: (A, B)): int) =
   ## sorts `t` according to `cmp`. This modifies the internal list
@@ -916,6 +939,11 @@ proc `$`*[A](t: CountTable[A]): string =
   ## The `$` operator for count tables.
   dollarImpl()
 
+proc `==`*[A](s, t: CountTable[A]): bool =
+  ## The `==` operator for count tables. Returns ``true`` iff both tables
+  ## contain the same keys with the same count. Insert order does not matter.
+  equalsImpl(s, t)
+
 proc inc*[A](t: var CountTable[A], key: A, val = 1) =
   ## increments `t[key]` by `val`.
   var index = rawGet(t, key)
@@ -1040,6 +1068,11 @@ proc `$`*[A](t: CountTableRef[A]): string =
   ## The `$` operator for count tables.
   dollarImpl()
 
+proc `==`*[A](s, t: CountTableRef[A]): bool =
+  ## The `==` operator for count tables. Returns ``true`` iff both tables
+  ## contain the same keys with the same count. Insert order does not matter.
+  result = s[] == t[]
+
 proc inc*[A](t: CountTableRef[A], key: A, val = 1) =
   ## increments `t[key]` by `val`.
   t[].inc(key, val)
diff --git a/tests/collections/ttables.nim b/tests/collections/ttables.nim
index 59fef4920..4f286d0ed 100644
--- a/tests/collections/ttables.nim
+++ b/tests/collections/ttables.nim
@@ -95,9 +95,24 @@ block orderedTableTest1:
   for key, val in mpairs(t): val = 99
   for val in mvalues(t): assert val == 99
 
+block orderedTableTest2:
+  var
+    s = initOrderedTable[string, int]()
+    t = initOrderedTable[string, int]()
+  assert s == t
+  for key, val in items(data): t[key] = val
+  assert s != t
+  for key, val in items(sorteddata): s[key] = val
+  assert s != t
+  t.clear()
+  assert s != t
+  for key, val in items(sorteddata): t[key] = val
+  assert s == t
+
 block countTableTest1:
   var s = data.toTable
   var t = initCountTable[string]()
+  
   for k in s.keys: t.inc(k)
   for k in t.keys: assert t[k] == 1
   t.inc("90", 3)
@@ -115,6 +130,24 @@ block countTableTest1:
     else: break
     inc i
 
+block countTableTest2:
+  var
+    s = initCountTable[int]()
+    t = initCountTable[int]()
+  assert s == t
+  s.inc(1)
+  assert s != t
+  t.inc(2)
+  assert s != t
+  t.inc(1)
+  assert s != t
+  s.inc(2)
+  assert s == t
+  s.inc(1)
+  assert s != t
+  t.inc(1)
+  assert s == t
+
 block mpairsTableTest1:
   var t = initTable[string, int]()
   t["a"] = 1