summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2015-07-03 11:46:59 +0200
committerAndreas Rumpf <rumpf_a@web.de>2015-07-03 11:46:59 +0200
commite43daf3d240207bab19c3014a8788717868d5897 (patch)
tree94d28b3188215ba7d104af488b7fac436d88df5e
parent60ac5e3e76fe24e015782a081da3f04f0000ea5f (diff)
parent414d69ccea7f3ef1a0481a121371e2f0ef7cff80 (diff)
downloadNim-e43daf3d240207bab19c3014a8788717868d5897.tar.gz
Merge pull request #3049 from bluenote10/devel
added hash function for ordinal types
-rw-r--r--lib/pure/hashes.nim4
-rw-r--r--tests/collections/thashes.nim75
2 files changed, 79 insertions, 0 deletions
diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim
index c303c7b4b..fdf0fdb0d 100644
--- a/lib/pure/hashes.nim
+++ b/lib/pure/hashes.nim
@@ -115,6 +115,10 @@ proc hash*(x: char): Hash {.inline.} =
   ## efficient hashing of characters
   result = ord(x)
 
+proc hash*[T: Ordinal](x: T): THash {.inline.} =
+  ## efficient hashing of other ordinal types (e.g. enums)
+  result = ord(x)
+
 proc hash*(x: string): Hash =
   ## efficient hashing of strings
   var h: Hash = 0
diff --git a/tests/collections/thashes.nim b/tests/collections/thashes.nim
new file mode 100644
index 000000000..b9c639414
--- /dev/null
+++ b/tests/collections/thashes.nim
@@ -0,0 +1,75 @@
+discard """
+  output: '''true'''
+"""
+
+import tables
+from hashes import THash
+
+# Test with int
+block:
+  var t = initTable[int,int]()
+  t[0] = 42
+  t[1] = t[0] + 1
+  assert(t[0] == 42)
+  assert(t[1] == 43)
+  let t2 = {1: 1, 2: 2}.toTable
+  assert(t2[2] == 2)
+
+# Test with char
+block:
+  var t = initTable[char,int]()
+  t['0'] = 42
+  t['1'] = t['0'] + 1
+  assert(t['0'] == 42)
+  assert(t['1'] == 43)
+  let t2 = {'1': 1, '2': 2}.toTable
+  assert(t2['2'] == 2)
+
+# Test with enum
+block:
+  type
+    E = enum eA, eB, eC
+  var t = initTable[E,int]()
+  t[eA] = 42
+  t[eB] = t[eA] + 1
+  assert(t[eA] == 42)
+  assert(t[eB] == 43)
+  let t2 = {eA: 1, eB: 2}.toTable
+  assert(t2[eB] == 2)
+
+# Test with range
+block:
+  type
+    R = range[1..10]
+  var t = initTable[R,int]() # causes warning, why?
+  t[1] = 42 # causes warning, why?
+  t[2] = t[1] + 1
+  assert(t[1] == 42)
+  assert(t[2] == 43)
+  let t2 = {1.R: 1, 2.R: 2}.toTable
+  assert(t2[2.R] == 2)
+
+# Test which combines the generics for tuples + ordinals
+block:
+  type
+    E = enum eA, eB, eC
+  var t = initTable[(string, E, int, char), int]()
+  t[("a", eA, 0, '0')] = 42
+  t[("b", eB, 1, '1')] = t[("a", eA, 0, '0')] + 1
+  assert(t[("a", eA, 0, '0')] == 42)
+  assert(t[("b", eB, 1, '1')] == 43)
+  let t2 = {("a", eA, 0, '0'): 1, ("b", eB, 1, '1'): 2}.toTable
+  assert(t2[("b", eB, 1, '1')] == 2)
+
+# Test to check if overloading is possible
+# Unfortunately, this does not seem to work for int
+# The same test with a custom hash(s: string) does
+# work though.
+block:
+  proc hash(x: int): THash {.inline.} =
+    echo "overloaded hash"
+    result = x
+  var t = initTable[int, int]()
+  t[0] = 0
+
+echo "true"